This notebook is part of an exploratory analysis of machine learning used to decompose hyperspectral datasets of hybrid perovskite nanoscale materials.
Two machine learning models are mainly used in this project: Nonnegative Matrix Factorization (NMF) and Variational Autoencoders (VAEs). This notebook implements semi-supervised VAE models to better represent the types of spectral features and their locations in the material.
Notebook Four: Semi-Supervised VAE
Imports, Functions, and Classes¶
Imports¶
from preprocessing import *
import torch
from torchvision.utils import make_grid
import pyroved as pv
import pyro.distributions as dist
import pyro
from pyroved.models.base import baseVAE
from pyroved.nets import fcDecoderNet, fcEncoderNet, sDecoderNet
from pyroved.utils import (
generate_grid, get_sampler, set_deterministic_mode, to_onehot, transform_coordinates)
save_directory = "./png-figures/" # modify to save figures as a specified file extension
file_extension = ".png"
SEM images: f1_img1, f2_img1 CL images: f1_img2, f2_img2 Denoised data: f1_sb_median, f2_sb_median 2D denoised data: f1_denoised_2d, f2_denoised_2d Example points: f1_x_points, f1_y_points, f2_x_points, f2_y_points Wavelengths and dimensions: f1_wav, f2_wav, f1_xpix, f1_ypix, f1_zpix, f2_xpix, f2_ypix, f2_zpix
Unsupervised Variational Autoencoder¶
An autoencoder is an unsupervised neural network model that learns two functions: an encoding function (transforms input into latent space representation with lower dimensionality) and a decoding function (recreates input data from latent representation). The autoencoder attempts to optimize the representation of unbalanced/non-linear data (as opposed to PCA or NMF, which are linear). It is more deterministic in its approach than a VAE.
Hyperparameters: Code size, number of layers, number of nodes per layer, and the loss function
Architecture: Input, encoder, latent space, decoder, and output
A variational autoencoder is a generative, semi-supervised autoencoder with the addition of regularized training (which prevents overfitting). This crucial additional step allows for each point in the latent space to yield meaningful data, allowing for generative processes. These are more probabilistic in nature and enforce a (generally Gaussian) distribution in the sampling process. The end result is a latent space that is optimized for clustering together similar data points while giving a continuous distribution across the entire latent space. This is achieved through minimizing the KL divergence (causing the mean to approach 0 and the standard deviation to approach 1).
Loss function: reconstruction term (Gradient descent) (makes encoding and decoding efficient) + regularization term (Kullback-Leibler Divergence) (creates regular latent space)
VAEs use a "reparameterization trick" to allow for backpropagation, which is impossible through a stochastic node. The process of sampling from a distribution that is parameterized by the model is not differentiable, and this is a problem for gradient-based approaches. There must be a method of making the predictions separate from the stochastic sampling element.
It accomplishes this by treating random sampling as a noise term which is now independent and not parameterized by the model. A Gaussian can be scaled by a sample from the noise distribution multiplied by the standard deviation added to the mean. This allows for further differentiation through the model.
We are primarily interested in the latent space representation of the data as this reveals to us the correlations in the data that the model detects. However many latent dimensions we specify in the training will be the number of principal components we analyze and their correlations to one another.
Semi-supervised machine learning involves aspects of both supervised and unsupervisded machine learning. A small portion of the training data is labeled, and this is used to classify the majority of the data, which is unlabeled. The goal here is to label several spectral features within the data and asses how well the model is able to pick up on the locations of these features through training in order to predict their location in new data.
Plot Code¶
vae_plot builds a plot of the latent space dimensions with two or three latent dimensions and plots points corresponding to single pixels in the x and y axes of the original dataset. The point is to show a relationship between different spectral features detected by the autoencoder. Below the plot is an image component of the latent representation of the data.
spectra_plot plots each spectrum in the image color mapped according to its value along a specified axis.
ssvae_plot plots the latent space and image reconstruction of SSVAE models
pointfinder_plot shows every spectrum with a certain x value (along a vertical line in the image).
spectsig_plot shows all labeled spectra color mapped according to each class
ssvae_label_plot shows the first 180 spectra the SSVAE model assigns to a specified class
spect_label_plot plot one spectrum from each class in the labeled data
custom_spect_label_plot plot one spectrum from each class in the latent representation of the data
# Plotting pixels containing entire spectra in a latent space and corresponding images
def vae_plot(suptitle, z_mean, xpix, ypix, scalebar_size, save=False):
rows = 2
columns = len(z_mean[0])
fig = plt.figure(figsize=(4,4))
fig.suptitle(suptitle, fontsize=10)
fig.patch.set_facecolor("white")
for i in range(rows):
for j in range(columns):
if i == 0: # First row
if columns == 2: # 2D Latent space
ax = fig.add_subplot(2, 2, j + 1)
ax.scatter(z_mean[:, 0], z_mean[:, 1], c=z_mean[:, j], cmap=cmap,
ec='black', lw=0.1, alpha=0.6, s=2)
ax.tick_params(axis='both', which='major', labelsize=4, direction='out',
length=2, width=0.5)
else: # 3D Latent space
ax = fig.add_subplot(2, 3, j + 1, projection='3d')
ax.scatter(z_mean[:, 0], z_mean[:, 1], z_mean[:, 2],
c=z_mean[:, j], cmap=cmap,
ec='black', lw=0.05, alpha=0.5, s=2)
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.zaxis.set_ticklabels([])
ax.set_xlabel("X", size=5, labelpad=-15)
ax.set_ylabel("Y", size=5, labelpad=-15)
ax.set_zlabel("Z", size=5, labelpad=-15)
if j == 0:
ax.view_init(30, -85)
elif j == 1:
ax.view_init(30, -40)
elif j == 2:
ax.view_init(30, 5)
if j == 0:
ax.set_title('Latent Space', size=7)
if i == 1: # Second row
if columns == 2: # 2D Latent Space
img = fig.add_subplot(2, 2, j+3)
else: # 3D Latent Space
img = fig.add_subplot(2, 3, j+4)
img.imshow(z_mean[:,j].reshape(ypix, xpix), cmap=cmap)
img.set_xticks([])
img.set_yticks([])
if j == (columns-1): # Add scalebar to bottom right image
scalebar = AnchoredSizeBar(img.transData, scalebar_size, " ",
"lower right", pad=0.2, color='#F2F2F2', frameon=False,
size_vertical=3, label_top=True)
img.add_artist(scalebar)
if save:
fig.savefig(save_directory + "unsupervised-vae/" + suptitle + file_extension)
# Spectra Plot (for determining latent dimensions)
def spectra_plot(suptitle, img, array, xpix, ypix, wav, save=False):
n = xpix*ypix # total number of spectra
cmap = mpl.colormaps['viridis'](np.linspace(0,1,n)) # create colormap
fig = plt.figure(figsize=(6,3))
fig.suptitle(suptitle, fontsize=10)
fig.patch.set_facecolor('white')
ax = fig.add_subplot()
ax.set_prop_cycle('color', list(cmap)) # colormaps each spectra from first to last in array
ax.tick_params(axis='both', which='major', labelsize=5, direction='out', length=2, width=0.5)
plt.xlim(short_wav - 5, long_wav + 5)
#ax.set_xticks([500, 750])
#ax.set_xticklabels([])
#plt.yscale('log')
for i in array:
ax.plot(wav, img[:,i[0],i[1]], lw=0.03, alpha=0.5)
if save:
fig.savefig(save_directory + "unsupervised-vae/" + suptitle + file_extension)
# SEMI-SUPERVISED VAE
# Plot the latent space and image reconstruction of SSVAE models
def ssvae_plot(suptitle, z_mean, z_labels, xpix, ypix, scalebar_size, save=False):
rows = 2
columns = 1
cmap = mpl.colormaps['viridis']
fig = plt.figure(figsize=(4,4))
fig.suptitle(suptitle, fontsize=10)
gs = GridSpec(rows, columns)
#fig.patch.set_facecolor('#00000000')
fig.patch.set_facecolor('white')
for i in range(rows):
column_count = 0
for j in range(columns):
if i == 0:
ax = fig.add_subplot(gs[0,column_count])
ax.scatter(z_mean[:,0], z_mean[:,1], c=z_labels, cmap=cmap,
ec='black', lw=0.05, alpha=0.6, s=2)
#ax.tick_params(axis='both', labelsize=10)
ax.set_xticks([])
ax.set_yticks([])
if i == 1:
img = fig.add_subplot(gs[1,column_count])
img.imshow(z_labels.reshape(ypix, xpix), cmap=cmap)
img.set_xticks([])
img.set_yticks([])
if column_count == (columns-1):
scalebar = AnchoredSizeBar(img.transData, scalebar_size, " ",
"lower right", pad=0.3, color='#F2F2F2', frameon=False,
size_vertical=3, label_top=True)
img.add_artist(scalebar)
column_count += 1
if save:
fig.savefig(save_directory + "semi-supervised-vae/" + suptitle + file_extension)
# Function to plot every spectrum with a certain x value (along a vertical line in the image)
def pointfinder_plot(img, x_pt, ypix, wav):
rows = ypix
columns = 1
fig = plt.figure(figsize=(4, rows))
for i in range(rows):
ax = fig.add_subplot(rows, columns, i + 1)
ax.plot(wav, img[:, i, x_pt], c=color[i], lw=2)
ax.text(220, 350, str([i, x_pt]), fontsize=5)
ax.set_xticks([])
ax.set_yticks([])
plt.show()
# Plot all spectra in each of the 4 classes
def spectsig_plot(suptitle, img, pts, wav, save=False):
rows = len(pts[0])
columns = 4
gs = GridSpec(rows, columns)
gs.update(wspace=0, hspace=0)
figsize = (columns*2, rows)
fig = plt.figure(figsize=figsize)
fig.patch.set_facecolor("white")
fig.suptitle(suptitle, fontsize=20)
#fig.subplots_adjust(top=0.95, bottom=0.1)
row_count = 0
for i in range(rows):
column_count = 0
for j in range(columns):
fig_plt = fig.add_subplot(gs[i,j])
fig_plt.plot(wav, img[pts[j][i][0],pts[j]
[i][1],:], c=cmap_list[j], lw=1)
plt.xlim(short_wav - 5, long_wav + 5) # Cropping the spectra shown in the plot
#fig_plt.tick_params(axis='both', direction='out', length=12, width=4)
fig_plt.set_xticks([])
fig_plt.set_yticks([])
#if column_count == 0:
#fig_plt.set_yticks([1000])
#fig_plt.set_yticklabels([])
#fig_plt.tick_params(axis='y', direction='out', length=12, width=4)
#if row_count == rows-1:
#fig_plt.set_xticks([400-short_wav, 750-long_wav])
#fig_plt.set_xticklabels([])
#fig_plt.tick_params(axis='x', direction='out', length=12, width=4)
column_count += 1
row_count += 1
if save:
fig.savefig(save_directory + "semi-supervised-vae/" + suptitle + file_extension)
plt.show()
# This plot shows the first 180 spectra the SSVAE model assigns to a specified class
def ssvae_label_plot(img, pts, wav, starting_index=0, save=False):
rows = 180
#rows = len(pts)
columns = 1
fig = plt.figure(figsize=(4, rows))
fig.patch.set_facecolor("white")
#fig.suptitle(suptitle, fontsize=30)
gs = GridSpec(rows, columns)
row_count = 0
for i in range(starting_index, starting_index + rows):
fig_plt = fig.add_subplot(gs[row_count,0])
fig_plt.plot(wav, img[:, pts[i,0], pts[i,1]],
c=color[row_count], lw=3)
plt.xticks([])
plt.yticks([])
#plt.text(220,350,str((int(pts[i][0]),int(pts[i][1]))))
plt.text(0, 0, str(i))
row_count += 1
#gs.tight_layout(fig, rect=[0,0.03,1,0.95])
if save:
fig.savefig(save_directory + "semi-supervised-vae/" + suptitle + file_extension)
plt.show()
# Plot one spectrum from each class in the labeled data
def spect_label_plot(suptitle, img, pts, wav, save=False):
rows = 1
columns = 4
gs = GridSpec(rows, columns)
gs.update(wspace=0,hspace=0.2)
figsize = (columns*4, rows*3)
fig = plt.figure(figsize=figsize)
fig.suptitle(suptitle, size = 20)
fig.patch.set_facecolor("white")
#fig.patch.set_facecolor('#00000000')
#fig.suptitle(suptitle, fontsize=30)
#fig.subplots_adjust(top=0.95, bottom=0.1)
row_count = 0
for i in range(rows):
column_count = 0
for j in range(columns):
fig_plt = fig.add_subplot(gs[i,j])
fig_plt.plot(wav, img[:,pts[j][i][0],pts[j][i][1]], c=cmap_list[j], lw=3)
#plt.text(300, 370, str(column_count))
#fig_plt.set_title(method_names[row_count] + point_names[column_count])
#fig_plt.tick_params(color=color[j])
plt.xlim(short_wav - 5, long_wav + 5) # Cropping the spectra shown in the plot
#fig_plt.tick_params(axis='both', direction='out', length=12, width=4)
#fig_plt.set_xticks([400, 550, 750])
fig_plt.set_yticks([])
fig_plt.set_xticks([])
column_count += 1
row_count += 1
if save:
fig.savefig(save_directory + "/semi-supervised-vae/" + suptitle + file_extension)
plt.show()
# Plot one spectrum from each class in the latent representation of the data
def custom_spect_label_plot(suptitle, img, pts, wav, save=False):
rows = 1
columns = 4
gs = GridSpec(rows, columns)
gs.update(wspace=0,hspace=0.2)
figsize = (columns*4, rows*3)
fig = plt.figure(figsize=figsize)
#fig.patch.set_facecolor("#00000000")
fig.patch.set_facecolor("white")
fig.suptitle(suptitle, fontsize=20)
#fig.subplots_adjust(top=0.95, bottom=0.1)
row_count = 0
for i in range(rows):
column_count = 0
for j in range(columns):
fig_plt = fig.add_subplot(gs[i, j])
fig_plt.plot(wav, img[:, pts[j][0], pts[j][1]], c=cmap_list[j], lw=3)
#plt.text(300, 370, str(column_count))
#fig_plt.set_title(method_names[row_count] + point_names[column_count])
#fig_plt.tick_params(color=color[j])
plt.xlim(short_wav, long_wav) # Cropping the spectra shown in the plot
fig_plt.tick_params(axis='both', direction='out', length=6, width=2)
#fig_plt.set_xticks([400, 750])
fig_plt.set_xticks([])
fig_plt.set_yticks([])
#fig_plt.set_xticklabels([])
#if column_count == 0:
#fig_plt.set_yticks([1000])
#fig_plt.set_yticklabels([])
#fig_plt.tick_params(axis='y', direction='out', length=12, width=4)
#if row_count == rows-1:
#fig_plt.set_xticks([400-short_wav, 750-long_wav])
#fig_plt.set_xticklabels([])
#fig_plt.tick_params(axis='x', direction='out', length=12, width=4)
column_count += 1
row_count += 1
if save:
fig.savefig(save_directory + "/semi-supervised-vae/" + suptitle + file_extension)
plt.show()
Invariant VAE (2 latent dimensions)¶
Variational autoencoder that enforces rotational, translational, and scale invariances. The goal is to remove any effect these transformations will cause in the encoding process and to pick up on the similarities in the features.
Grain 1¶
Code¶
First step: Transpose denoised array, reshape to 1D, normalize entire dataset, and reshape to 2D
Second step: Convert from Numpy array to PyTorch tensor, then find number of samples (spectra) and signal (number of points in image along x and y axes containing spectra)
(pv.utils.init_dataloader: Returns initialized PyTorch dataloader, which is used by pyroVEDās trainers. The inputs are torch Tensor objects containing training data and, optionally, labels.)
Third step: Create a dataloader object with unsqueezed training data. This is the entire hyperspectral array reshaped into 2 dimensions with another dimension of size one inserted into the array
(pyroved.trainers.SVItrainer: Stochastic variational inference (SVI) trainer for unsupervised and class-conditioned VED models consisting of one encoder and one decoder.)
Fourth step: An invariant VAE model with 2 latent dimensions is created along with an SVI trainer. Then, 50 epochs are run with every 10 epochs printing the training loss, showing the convergence to local minima.
Fifth step: pv.models.iVAE.encode returns the mean and standard deviation of the Z (latent) space, giving an array of image points (20008 for Figure 1), each containing an entire spectrum, plotted on an axis of specified latent dimensions (in this case, 2)
# Reshaping the 2D array to 1D. Imagine the 3D hyperspectral image, take the top left pixel's (from the perspective of the x-y plane)
# spectrum, add the spectrum of the pixel to the right to the end, and continue left to right, top to bottom, until the entire image is 1D.
f1_denoised_1d_transpose = f1_denoised_2d.transpose(1,0).reshape(f1_zpix*f1_ypix*f1_xpix)
# Normalize the entire 1D array, then reshape it to 2D, pixels by spectra, arranged left to right and top to bottom
f1_denoised_2d_norm = normalize(f1_denoised_1d_transpose).reshape(f1_xpix*f1_ypix, f1_zpix)
# Convert to Torch tensor object
f1_denoised_2d_norm_t = torch.from_numpy(np.array(f1_denoised_2d_norm).astype('float64')).float()
f1_n_samples = f1_denoised_2d_norm_t.size()[0] # number of spectral points
f1_l_signal = f1_denoised_2d_norm_t.size()[1] # number of spectra
f1_train_data = f1_denoised_2d_norm_t.clone()
f1_train_loader = pv.utils.init_dataloader(f1_train_data.unsqueeze(1), batch_size=64)
f1_in_dim = (f1_l_signal,)
# Gradually increase the weight of the KL Divergence term in the loss function with each epoch
f1_kl_scale = torch.linspace(start=.001, end=.01, steps=50)
# Training the model
f1_vae = pv.models.iVAE(f1_in_dim, latent_dim=2, invariances=None, sampler_d="gaussian")
f1_vae_trainer = pv.trainers.SVItrainer(f1_vae)
for e in range(50):
sc = f1_kl_scale[e] if e < len(f1_kl_scale) else f1_kl_scale[-1]
f1_vae_trainer.step(f1_train_loader, scale_factor=sc)
if e//10 == e/10:
f1_vae_trainer.print_statistics()
f1_vae_z_mean, f1_vae_z_sd = f1_vae.encode(f1_train_data)
f1_vae_z_mean = normalize(f1_vae_z_mean)
f1_vae_z_sd = normalize(f1_vae_z_sd)
Epoch: 1 Training loss: 157.6064 Epoch: 11 Training loss: 145.6802 Epoch: 21 Training loss: 145.6788 Epoch: 31 Training loss: 145.6842 Epoch: 41 Training loss: 145.6906
vae_plot("Vanilla VAE Grain 1", f1_vae_z_mean, f1_xpix, f1_ypix, 50)
Grain 2¶
Code¶
f2_denoised_1d_transpose = f2_denoised_2d.transpose(1,0).reshape(f2_zpix*f2_ypix*f2_xpix)
f2_denoised_2d_norm = normalize(f2_denoised_1d_transpose).reshape(f2_ypix*f2_xpix, f2_zpix)
f2_denoised_2d_norm_t = torch.from_numpy(np.array(f2_denoised_2d_norm).astype('float64')).float()
f2_n_samples = f2_denoised_2d_norm_t.size()[0] # number of spectra
f2_l_signal = f2_denoised_2d_norm_t.size()[1] # number of spectral points
f2_train_data = f2_denoised_2d_norm_t.clone()
f2_train_loader = pv.utils.init_dataloader(f2_train_data.unsqueeze(1), batch_size=64)
f2_in_dim = (f2_l_signal,)
f2_kl_scale = torch.linspace(.001, .01, 50)
# Training the model
f2_vae = pv.models.iVAE(f2_in_dim, latent_dim=2, invariances=None, sampler_d="gaussian")
f2_vae_trainer = pv.trainers.SVItrainer(f2_vae)
for e in range(50):
sc = f2_kl_scale[e] if e < len(f2_kl_scale) else f2_kl_scale[-1]
f2_vae_trainer.step(f2_train_loader, scale_factor=sc)
if e//10 == e/10:
f2_vae_trainer.print_statistics()
f2_vae_z_mean, f2_vae_z_sd = f2_vae.encode(f2_denoised_2d_norm_t)
f2_vae_z_mean = normalize(f2_vae_z_mean)
f2_vae_z_sd = normalize(f2_vae_z_sd)
Epoch: 1 Training loss: 179.1582 Epoch: 11 Training loss: 145.7374 Epoch: 21 Training loss: 145.7132 Epoch: 31 Training loss: 145.7104 Epoch: 41 Training loss: 145.6995
vae_plot("Vanilla VAE Grain 2", f2_vae_z_mean, f2_xpix, f2_ypix, 33.333333333)
Semi-Supervised VAE on Grain 1¶
Semi-supervised machine learning involves aspects of both supervised and unsupervisded machine learning. A small portion of the training data is labeled, and this is used to classify the majority of the data, which is unlabeled. The goal here is to label several spectral features within the data and asses how well the model is able to pick up on the locations of these features through training in order to predict their location in new data.
Preparing Data¶
Plot spectral signature classes¶
First, manually determine 6 examples of each of the 4 features present in the material, giving a labeled set of 24 spectra
pointfinder_plot(f1_img2, 9, f1_ypix, f1_wav)
# arrays of points labeled 0 to 3, totalling 4 classes
# format: [y, x]
f1_pts0 = [[50,50], [40,23], [40,21], [113,69], [93,75], [80,73], [4,4], [1,5], [55,100], [42,92]]
f1_pts1 = [[65,10], [67,17], [68,17], [69,17], [70,17], [74,17], [53,7], [52,7], [54,7], [74,9]]
f1_pts2 = [[22,142], [95,72], [96,72], [96,73], [95,71], [9,65], [47,8], [45,7], [43,7], [48,8]]
f1_pts3 = [[89,53], [9,67], [72,9], [7,69], [95,69], [7,72], [46,4], [42,4], [55,7], [42,8]]
f1_pts = [f1_pts0, f1_pts1, f1_pts2, f1_pts3]
# Reshape normalized 2D data to 3D
f1_denoised_3d_norm_t = f1_denoised_2d_norm_t.reshape(f1_ypix, f1_xpix, f1_zpix)
# Reshape denoided 2D data to 3D
f1_denoised_3d = np.reshape(f1_sb_median, (f1_zpix, f1_ypix, f1_xpix), order='C')
spectsig_plot("Four Classes of Spectral Features", f1_denoised_3d_norm_t, f1_pts, f1_wav)
Modeling Data¶
X_sup: 16 labeled spectra for supervised training
y_sup: one-hot labels for the spectra (tensor of same size as X_sup)
X_val: 8 labeled spectra for validation step
y_val: labels for validation step
X_unsup: the rest of the spectra, with the above spectra replaced with zeros
# Create normalized, denoised, hyperspectral image
f1_denoised_3d_norm = normalize(f1_denoised_1d_transpose).reshape(f1_ypix, f1_xpix, f1_zpix)
# Labeled data
n_samples = len(f1_pts0)
n_sup = n_samples - 3 # number of supervised samples
n_val = 3 # number of validation samples
f1_X_sup = torch.stack((f1_denoised_3d_norm_t[f1_pts0[0][0],f1_pts0[0][1],:],
f1_denoised_3d_norm_t[f1_pts0[1][0],f1_pts0[1][1],:],
f1_denoised_3d_norm_t[f1_pts0[2][0],f1_pts0[2][1],:],
f1_denoised_3d_norm_t[f1_pts0[3][0],f1_pts0[3][1],:],
f1_denoised_3d_norm_t[f1_pts0[4][0],f1_pts0[4][1],:],
f1_denoised_3d_norm_t[f1_pts0[5][0],f1_pts0[5][1],:],
f1_denoised_3d_norm_t[f1_pts0[6][0],f1_pts0[6][1],:],
f1_denoised_3d_norm_t[f1_pts1[0][0],f1_pts1[0][1],:],
f1_denoised_3d_norm_t[f1_pts1[1][0],f1_pts1[1][1],:],
f1_denoised_3d_norm_t[f1_pts1[2][0],f1_pts1[2][1],:],
f1_denoised_3d_norm_t[f1_pts1[3][0],f1_pts1[3][1],:],
f1_denoised_3d_norm_t[f1_pts1[4][0],f1_pts1[4][1],:],
f1_denoised_3d_norm_t[f1_pts1[5][0],f1_pts1[5][1],:],
f1_denoised_3d_norm_t[f1_pts1[6][0],f1_pts1[6][1],:],
f1_denoised_3d_norm_t[f1_pts2[0][0],f1_pts2[0][1],:],
f1_denoised_3d_norm_t[f1_pts2[1][0],f1_pts2[1][1],:],
f1_denoised_3d_norm_t[f1_pts2[2][0],f1_pts2[2][1],:],
f1_denoised_3d_norm_t[f1_pts2[3][0],f1_pts2[3][1],:],
f1_denoised_3d_norm_t[f1_pts2[4][0],f1_pts2[4][1],:],
f1_denoised_3d_norm_t[f1_pts2[5][0],f1_pts2[5][1],:],
f1_denoised_3d_norm_t[f1_pts2[6][0],f1_pts2[6][1],:],
f1_denoised_3d_norm_t[f1_pts3[0][0],f1_pts3[0][1],:],
f1_denoised_3d_norm_t[f1_pts3[1][0],f1_pts3[1][1],:],
f1_denoised_3d_norm_t[f1_pts3[2][0],f1_pts3[2][1],:],
f1_denoised_3d_norm_t[f1_pts3[3][0],f1_pts3[3][1],:],
f1_denoised_3d_norm_t[f1_pts3[4][0],f1_pts3[4][1],:],
f1_denoised_3d_norm_t[f1_pts3[5][0],f1_pts3[5][1],:],
f1_denoised_3d_norm_t[f1_pts3[6][0],f1_pts3[6][1],:])).float()
f1_sup_labels = torch.cat([torch.zeros(n_sup), torch.ones(n_sup),
2*torch.ones(n_sup), 3*torch.ones(n_sup)])
f1_y_sup = pv.utils.to_onehot(f1_sup_labels.long(), n=4) # create onehot array for supervised labels
f1_X_val = torch.stack((f1_denoised_3d_norm_t[f1_pts0[7][0],f1_pts0[7][1],:],
f1_denoised_3d_norm_t[f1_pts0[8][0],f1_pts0[8][1],:],
f1_denoised_3d_norm_t[f1_pts0[9][0],f1_pts0[8][1],:],
f1_denoised_3d_norm_t[f1_pts1[7][0],f1_pts1[7][1],:],
f1_denoised_3d_norm_t[f1_pts1[8][0],f1_pts1[8][1],:],
f1_denoised_3d_norm_t[f1_pts1[9][0],f1_pts1[9][1],:],
f1_denoised_3d_norm_t[f1_pts2[7][0],f1_pts2[7][1],:],
f1_denoised_3d_norm_t[f1_pts2[8][0],f1_pts2[8][1],:],
f1_denoised_3d_norm_t[f1_pts2[9][0],f1_pts2[9][1],:],
f1_denoised_3d_norm_t[f1_pts3[7][0],f1_pts3[7][1],:],
f1_denoised_3d_norm_t[f1_pts3[8][0],f1_pts3[8][1],:],
f1_denoised_3d_norm_t[f1_pts3[9][0],f1_pts3[9][1],:])).float()
#f1_X_val = torch.cat(f1_X_val)
f1_val_labels = torch.cat([torch.zeros(n_val), torch.ones(n_val),
2*torch.ones(n_val), 3*torch.ones(n_val)])
f1_y_val = pv.utils.to_onehot(f1_val_labels.long(), n=4) # create onehot array for validation labels
# Remove all labeled samples from unlabeled data by setting them to zero
f1_X_unsup = f1_denoised_3d_norm_t
for i in range(n_samples):
for j in range(4):
f1_X_unsup[f1_pts[j][i][0], f1_pts[j][i][1], :] *= 0
f1_X_unsup = f1_X_unsup.reshape(f1_xpix*f1_ypix, f1_zpix)
# Randomly shuffle points in image
#f1_X_unsup = f1_X_unsup[torch.randperm(f1_X_unsup.size()[0])]
(f1_loader_unsup, f1_loader_sup,
f1_loader_val) = pv.utils.init_ssvae_dataloaders(
f1_X_unsup, (f1_X_sup, f1_y_sup), (f1_X_val, f1_y_val), batch_size=64)
r = (len(f1_X_sup) + len(f1_X_val)) / (len(f1_X_unsup))
print("Ratio of labeled data to unlabeled data: {}".format(r))
Ratio of labeled data to unlabeled data: 0.001999200319872051
# Train the SSVAE model
f1_ss_data_dim = (f1_X_unsup.shape[1],)
latent_dim = 2
num_classes = 4
# Initialize model
#f1_ssvae = pv.models.ss_reg_iVAE(
# f1_ss_data_dim, latent_dim, num_classes, invariances=None)
f1_ssvae = pv.models.ssiVAE(
f1_ss_data_dim, latent_dim, num_classes, invariances=None)
# Initialize trainer
f1_ss_trainer = pv.trainers.auxSVItrainer(f1_ssvae, task='classification')
# Gradually increase KL weight from 1 to 2 in the first 30 epochs
f1_ss_kl_scale = torch.linspace(1, 2, 30)
# Train model for n epochs
for e in range(50):
sc = f1_ss_kl_scale[e] if e < len(f1_ss_kl_scale) else f1_ss_kl_scale[-1]
f1_ss_trainer.step(f1_loader_unsup, f1_loader_sup, f1_loader_val,
aux_loss_multiplier=50, scale_factor=sc, sampler_d='gaussian')
f1_ss_trainer.print_statistics()
# Plot learned latent manifolds every 10 epoch
#if (e+1) % 10 == 0:
#plot_manifolds(f1_ssvae)
Epoch: 1 Training loss: 82.3200, Test accuracy: 0.2500 Epoch: 2 Training loss: 56.0877, Test accuracy: 0.2500 Epoch: 3 Training loss: 54.5155, Test accuracy: 0.2500 Epoch: 4 Training loss: 54.0529, Test accuracy: 0.3333 Epoch: 5 Training loss: 53.9958, Test accuracy: 0.2500 Epoch: 6 Training loss: 53.9822, Test accuracy: 0.3333 Epoch: 7 Training loss: 53.9917, Test accuracy: 0.3333 Epoch: 8 Training loss: 54.0051, Test accuracy: 0.3333 Epoch: 9 Training loss: 54.0207, Test accuracy: 0.3333 Epoch: 10 Training loss: 54.0421, Test accuracy: 0.3333 Epoch: 11 Training loss: 54.0690, Test accuracy: 0.3333 Epoch: 12 Training loss: 54.0930, Test accuracy: 0.3333 Epoch: 13 Training loss: 54.1123, Test accuracy: 0.2500 Epoch: 14 Training loss: 54.1381, Test accuracy: 0.2500 Epoch: 15 Training loss: 54.1642, Test accuracy: 0.3333 Epoch: 16 Training loss: 54.1878, Test accuracy: 0.3333 Epoch: 17 Training loss: 54.2150, Test accuracy: 0.3333 Epoch: 18 Training loss: 54.2338, Test accuracy: 0.3333 Epoch: 19 Training loss: 54.2592, Test accuracy: 0.3333 Epoch: 20 Training loss: 54.2802, Test accuracy: 0.3333 Epoch: 21 Training loss: 54.3063, Test accuracy: 0.3333 Epoch: 22 Training loss: 54.3245, Test accuracy: 0.3333 Epoch: 23 Training loss: 54.3407, Test accuracy: 0.3333 Epoch: 24 Training loss: 54.2891, Test accuracy: 0.3333 Epoch: 25 Training loss: 54.1891, Test accuracy: 0.3333 Epoch: 26 Training loss: 54.1486, Test accuracy: 0.3333 Epoch: 27 Training loss: 54.0379, Test accuracy: 0.3333 Epoch: 28 Training loss: 53.9685, Test accuracy: 0.3333 Epoch: 29 Training loss: 53.9524, Test accuracy: 0.3333 Epoch: 30 Training loss: 53.9416, Test accuracy: 0.3333 Epoch: 31 Training loss: 53.9302, Test accuracy: 0.3333 Epoch: 32 Training loss: 53.9260, Test accuracy: 0.3333 Epoch: 33 Training loss: 53.9220, Test accuracy: 0.3333 Epoch: 34 Training loss: 53.9255, Test accuracy: 0.3333 Epoch: 35 Training loss: 53.9218, Test accuracy: 0.3333 Epoch: 36 Training loss: 53.9196, Test accuracy: 0.3333 Epoch: 37 Training loss: 53.9266, Test accuracy: 0.3333 Epoch: 38 Training loss: 53.9149, Test accuracy: 0.3333 Epoch: 39 Training loss: 53.9187, Test accuracy: 0.3333 Epoch: 40 Training loss: 53.9155, Test accuracy: 0.3333 Epoch: 41 Training loss: 53.9236, Test accuracy: 0.3333 Epoch: 42 Training loss: 53.9145, Test accuracy: 0.3333 Epoch: 43 Training loss: 53.9206, Test accuracy: 0.3333 Epoch: 44 Training loss: 53.9099, Test accuracy: 0.3333 Epoch: 45 Training loss: 53.9234, Test accuracy: 0.3333 Epoch: 46 Training loss: 53.9131, Test accuracy: 0.3333 Epoch: 47 Training loss: 53.9183, Test accuracy: 0.3333 Epoch: 48 Training loss: 53.9132, Test accuracy: 0.3333 Epoch: 49 Training loss: 53.9174, Test accuracy: 0.3333 Epoch: 50 Training loss: 53.9123, Test accuracy: 0.3333
#f1_ssvae.manifold2d(d=5, extent=[-5,5,-5,5])
#for i in range(2):
# f1_ssvae.manifold_traversal(8, i, cmap='viridis')
f1_ssvae_z_mean, f1_ssvae_z_sd, f1_ssvae_z_labels = f1_ssvae.encode(f1_train_data)
f1_ssvae_z_mean = normalize(f1_ssvae_z_mean)
f1_ssvae_z_sd = normalize(f1_ssvae_z_sd)
f1_ssvae_z_labels_2d = f1_ssvae_z_labels.reshape(f1_ypix,f1_xpix)
Labels¶
f1_ssvae_0_labels = (f1_ssvae_z_labels_2d == 0).nonzero(as_tuple=False)
f1_ssvae_1_labels = (f1_ssvae_z_labels_2d == 1).nonzero(as_tuple=False)
f1_ssvae_2_labels = (f1_ssvae_z_labels_2d == 2).nonzero(as_tuple=False)
f1_ssvae_3_labels = (f1_ssvae_z_labels_2d == 3).nonzero(as_tuple=False)
Label lists¶
print( len(f1_ssvae_0_labels),
len(f1_ssvae_1_labels),
len(f1_ssvae_2_labels),
len(f1_ssvae_3_labels),
len(f1_ssvae_0_labels)+len(f1_ssvae_1_labels)+len(f1_ssvae_2_labels)+len(f1_ssvae_3_labels))
f1_ssvae_0_labels
tensor([[ 1, 80],
[ 1, 81],
[ 1, 86],
...,
[104, 55],
[113, 4],
[113, 5]])
f1_ssvae_1_labels
tensor([[ 0, 26],
[ 0, 27],
[ 0, 28],
...,
[121, 161],
[121, 162],
[121, 163]])
f1_ssvae_2_labels
tensor([[ 0, 0],
[ 0, 1],
[ 0, 2],
...,
[121, 134],
[121, 146],
[121, 147]])
f1_ssvae_3_labels
tensor([[ 0, 94],
[ 0, 95],
[ 1, 6],
...,
[121, 88],
[121, 112],
[121, 113]])
oh_no = 0
for i in f1_ssvae_0_labels:
if i in f1_ssvae_1_labels:
oh_no += 1
oh_no
5531
not_in = 0
what = []
for i in f1_ssvae_0_labels:
if i in f1_ssvae_2_labels:
not_in += 1
what.append(i.tolist())
print(not_in, '\n')
print(what)
5531 [[1, 80], [1, 81], [1, 86], [1, 87], [1, 95], [1, 96], [1, 97], [2, 29], [2, 30], [2, 31], [2, 32], [2, 44], [2, 46], [2, 47], [2, 48], [2, 49], [2, 51], [2, 58], [2, 59], [2, 60], [2, 61], [2, 62], [2, 63], [2, 68], [2, 69], [2, 73], [2, 74], [2, 75], [2, 76], [2, 77], [2, 78], [2, 79], [2, 80], [2, 81], [2, 82], [2, 83], [2, 95], [2, 96], [2, 97], [2, 98], [2, 99], [2, 100], [2, 101], [2, 102], [2, 103], [2, 104], [2, 154], [2, 155], [3, 29], [3, 30], [3, 31], [3, 32], [3, 33], [3, 34], [3, 35], [3, 36], [3, 37], [3, 38], [3, 39], [3, 40], [3, 43], [3, 44], [3, 45], [3, 46], [3, 47], [3, 48], [3, 52], [3, 53], [3, 54], [3, 55], [3, 56], [3, 57], [3, 58], [3, 59], [3, 60], [3, 61], [3, 62], [3, 63], [3, 64], [3, 65], [3, 66], [3, 67], [3, 68], [3, 69], [3, 70], [3, 71], [3, 72], [3, 73], [3, 74], [3, 75], [3, 76], [3, 77], [3, 78], [3, 98], [3, 99], [3, 100], [3, 101], [3, 102], [3, 103], [3, 104], [3, 111], [3, 112], [3, 113], [3, 114], [3, 115], [3, 150], [3, 151], [3, 152], [3, 153], [3, 154], [4, 23], [4, 24], [4, 25], [4, 29], [4, 30], [4, 31], [4, 32], [4, 33], [4, 34], [4, 35], [4, 36], [4, 37], [4, 38], [4, 39], [4, 40], [4, 41], [4, 42], [4, 46], [4, 47], [4, 48], [4, 49], [4, 52], [4, 53], [4, 54], [4, 55], [4, 56], [4, 57], [4, 58], [4, 59], [4, 60], [4, 61], [4, 62], [4, 63], [4, 64], [4, 65], [4, 66], [4, 67], [4, 68], [4, 69], [4, 70], [4, 71], [4, 72], [4, 73], [4, 74], [4, 75], [4, 98], [4, 99], [4, 100], [4, 101], [4, 102], [4, 103], [4, 104], [4, 105], [4, 106], [4, 112], [4, 114], [4, 149], [4, 150], [4, 151], [4, 152], [5, 15], [5, 16], [5, 17], [5, 18], [5, 23], [5, 24], [5, 25], [5, 29], [5, 30], [5, 31], [5, 32], [5, 33], [5, 34], [5, 35], [5, 36], [5, 37], [5, 38], [5, 39], [5, 40], [5, 41], [5, 42], [5, 43], [5, 44], [5, 45], [5, 46], [5, 47], [5, 48], [5, 49], [5, 50], [5, 51], [5, 52], [5, 53], [5, 54], [5, 55], [5, 56], [5, 57], [5, 58], [5, 59], [5, 60], [5, 61], [5, 62], [5, 63], [5, 64], [5, 65], [5, 66], [5, 67], [5, 68], [5, 69], [5, 70], [5, 99], [5, 100], [5, 101], [5, 102], [5, 103], [5, 104], [5, 105], [5, 106], [5, 107], [5, 108], [5, 109], [5, 110], [5, 114], [5, 115], [5, 119], [5, 120], [5, 121], [5, 129], [5, 130], [5, 131], [5, 132], [5, 145], [5, 146], [5, 147], [5, 148], [5, 149], [5, 150], [5, 151], [5, 152], [6, 15], [6, 16], [6, 17], [6, 18], [6, 19], [6, 20], [6, 21], [6, 22], [6, 23], [6, 24], [6, 25], [6, 26], [6, 27], [6, 28], [6, 29], [6, 30], [6, 31], [6, 32], [6, 33], [6, 34], [6, 35], [6, 36], [6, 37], [6, 38], [6, 39], [6, 40], [6, 41], [6, 42], [6, 43], [6, 44], [6, 45], [6, 46], [6, 47], [6, 48], [6, 49], [6, 50], [6, 51], [6, 52], [6, 53], [6, 54], [6, 55], [6, 56], [6, 57], [6, 58], [6, 59], [6, 60], [6, 61], [6, 62], [6, 63], [6, 64], [6, 65], [6, 66], [6, 67], [6, 102], [6, 103], [6, 104], [6, 105], [6, 106], [6, 107], [6, 108], [6, 109], [6, 110], [6, 111], [6, 112], [6, 113], [6, 114], [6, 115], [6, 116], [6, 117], [6, 118], [6, 119], [6, 120], [6, 121], [6, 140], [6, 141], [6, 142], [6, 148], [6, 149], [6, 150], [6, 151], [7, 11], [7, 15], [7, 16], [7, 17], [7, 18], [7, 22], [7, 23], [7, 24], [7, 25], [7, 26], [7, 27], [7, 28], [7, 29], [7, 30], [7, 31], [7, 32], [7, 33], [7, 34], [7, 35], [7, 36], [7, 40], [7, 41], [7, 42], [7, 43], [7, 44], [7, 45], [7, 46], [7, 47], [7, 48], [7, 49], [7, 50], [7, 51], [7, 52], [7, 53], [7, 54], [7, 55], [7, 56], [7, 57], [7, 58], [7, 59], [7, 60], [7, 61], [7, 62], [7, 63], [7, 105], [7, 106], [7, 107], [7, 108], [7, 109], [7, 110], [7, 111], [7, 112], [7, 113], [7, 114], [7, 115], [7, 116], [7, 117], [7, 118], [7, 119], [7, 120], [7, 121], [7, 122], [7, 130], [7, 136], [7, 137], [7, 145], [7, 146], [7, 147], [7, 148], [7, 149], [7, 150], [7, 151], [7, 152], [7, 153], [8, 3], [8, 4], [8, 12], [8, 13], [8, 14], [8, 15], [8, 16], [8, 24], [8, 25], [8, 26], [8, 30], [8, 31], [8, 32], [8, 33], [8, 34], [8, 35], [8, 36], [8, 37], [8, 38], [8, 39], [8, 40], [8, 41], [8, 42], [8, 43], [8, 44], [8, 45], [8, 46], [8, 47], [8, 48], [8, 49], [8, 50], [8, 53], [8, 54], [8, 55], [8, 56], [8, 57], [8, 58], [8, 59], [8, 60], [8, 61], [8, 106], [8, 107], [8, 108], [8, 109], [8, 110], [8, 111], [8, 112], [8, 113], [8, 114], [8, 115], [8, 116], [8, 117], [8, 118], [8, 119], [8, 120], [8, 121], [8, 122], [8, 127], [8, 132], [8, 133], [8, 134], [8, 135], [8, 136], [8, 137], [8, 138], [8, 139], [8, 140], [8, 141], [8, 142], [8, 143], [8, 144], [8, 145], [8, 146], [8, 147], [8, 148], [8, 149], [8, 150], [8, 151], [9, 20], [9, 21], [9, 22], [9, 30], [9, 31], [9, 32], [9, 33], [9, 34], [9, 35], [9, 36], [9, 37], [9, 38], [9, 39], [9, 40], [9, 41], [9, 42], [9, 43], [9, 44], [9, 45], [9, 46], [9, 47], [9, 48], [9, 49], [9, 50], [9, 51], [9, 52], [9, 53], [9, 54], [9, 55], [9, 56], [9, 57], [9, 109], [9, 110], [9, 111], [9, 112], [9, 113], [9, 114], [9, 115], [9, 116], [9, 117], [9, 118], [9, 119], [9, 120], [9, 121], [9, 122], [9, 123], [9, 124], [9, 125], [9, 127], [9, 130], [9, 132], [9, 133], [9, 134], [9, 135], [9, 136], [9, 140], [9, 141], [9, 142], [9, 143], [9, 144], [9, 145], [9, 146], [9, 147], [9, 148], [9, 149], [9, 150], [9, 151], [9, 154], [9, 155], [9, 163], [10, 19], [10, 20], [10, 21], [10, 22], [10, 27], [10, 28], [10, 29], [10, 30], [10, 31], [10, 32], [10, 33], [10, 34], [10, 35], [10, 36], [10, 37], [10, 38], [10, 39], [10, 42], [10, 43], [10, 44], [10, 45], [10, 46], [10, 47], [10, 48], [10, 49], [10, 50], [10, 51], [10, 52], [10, 53], [10, 54], [10, 55], [10, 56], [10, 57], [10, 58], [10, 108], [10, 109], [10, 110], [10, 111], [10, 112], [10, 113], [10, 114], [10, 115], [10, 116], [10, 117], [10, 118], [10, 119], [10, 120], [10, 121], [10, 122], [10, 123], [10, 124], [10, 125], [10, 126], [10, 127], [10, 128], [10, 129], [10, 130], [10, 131], [10, 132], [10, 133], [10, 134], [10, 135], [10, 136], [10, 137], [10, 142], [10, 143], [10, 144], [10, 145], [10, 146], [10, 147], [10, 148], [10, 149], [10, 150], [10, 151], [11, 15], [11, 16], [11, 19], [11, 20], [11, 21], [11, 26], [11, 27], [11, 30], [11, 31], [11, 32], [11, 33], [11, 34], [11, 35], [11, 36], [11, 37], [11, 38], [11, 39], [11, 40], [11, 41], [11, 42], [11, 43], [11, 44], [11, 45], [11, 46], [11, 47], [11, 48], [11, 49], [11, 53], [11, 54], [11, 55], [11, 56], [11, 57], [11, 109], [11, 110], [11, 111], [11, 112], [11, 113], [11, 114], [11, 115], [11, 116], [11, 117], [11, 118], [11, 119], [11, 120], [11, 121], [11, 122], [11, 132], [11, 133], [11, 134], [11, 135], [11, 136], [11, 137], [11, 138], [11, 139], [11, 140], [11, 141], [11, 142], [11, 143], [11, 144], [11, 145], [11, 146], [11, 147], [11, 148], [11, 149], [11, 150], [12, 0], [12, 1], [12, 2], [12, 3], [12, 12], [12, 13], [12, 14], [12, 15], [12, 16], [12, 19], [12, 20], [12, 21], [12, 22], [12, 26], [12, 27], [12, 28], [12, 29], [12, 30], [12, 31], [12, 32], [12, 33], [12, 34], [12, 35], [12, 36], [12, 37], [12, 38], [12, 39], [12, 40], [12, 41], [12, 42], [12, 43], [12, 44], [12, 45], [12, 46], [12, 47], [12, 111], [12, 112], [12, 113], [12, 114], [12, 115], [12, 116], [12, 117], [12, 118], [12, 119], [12, 120], [12, 121], [12, 122], [12, 123], [12, 124], [12, 125], [12, 126], [12, 127], [12, 128], [12, 129], [12, 132], [12, 133], [12, 134], [12, 135], [12, 136], [12, 137], [12, 138], [12, 139], [12, 140], [12, 141], [12, 142], [12, 143], [12, 144], [12, 145], [12, 146], [12, 147], [12, 148], [13, 1], [13, 2], [13, 11], [13, 12], [13, 15], [13, 16], [13, 17], [13, 24], [13, 25], [13, 26], [13, 27], [13, 28], [13, 30], [13, 31], [13, 32], [13, 33], [13, 34], [13, 35], [13, 36], [13, 37], [13, 38], [13, 39], [13, 40], [13, 41], [13, 42], [13, 43], [13, 44], [13, 45], [13, 98], [13, 116], [13, 117], [13, 118], [13, 119], [13, 120], [13, 121], [13, 122], [13, 123], [13, 124], [13, 125], [13, 126], [13, 127], [13, 128], [13, 129], [13, 130], [13, 131], [13, 132], [13, 133], [13, 134], [13, 135], [13, 137], [13, 139], [13, 140], [13, 141], [13, 142], [13, 143], [13, 144], [13, 145], [13, 146], [13, 147], [13, 148], [13, 149], [14, 3], [14, 18], [14, 19], [14, 20], [14, 21], [14, 25], [14, 26], [14, 27], [14, 28], [14, 29], [14, 30], [14, 31], [14, 32], [14, 33], [14, 34], [14, 35], [14, 36], [14, 37], [14, 38], [14, 39], [14, 40], [14, 41], [14, 42], [14, 43], [14, 44], [14, 59], [14, 60], [14, 84], [14, 97], [14, 98], [14, 102], [14, 116], [14, 117], [14, 118], [14, 119], [14, 120], [14, 121], [14, 122], [14, 123], [14, 124], [14, 125], [14, 126], [14, 127], [14, 128], [14, 129], [14, 130], [14, 131], [14, 132], [14, 133], [14, 134], [14, 135], [14, 136], [14, 137], [14, 138], [14, 139], [14, 140], [14, 141], [14, 142], [14, 143], [14, 144], [14, 145], [14, 146], [14, 147], [14, 153], [14, 154], [15, 12], [15, 13], [15, 18], [15, 19], [15, 20], [15, 21], [15, 22], [15, 23], [15, 24], [15, 25], [15, 26], [15, 27], [15, 28], [15, 29], [15, 30], [15, 31], [15, 32], [15, 33], [15, 34], [15, 35], [15, 36], [15, 37], [15, 38], [15, 39], [15, 40], [15, 41], [15, 57], [15, 58], [15, 59], [15, 60], [15, 68], [15, 69], [15, 119], [15, 120], [15, 121], [15, 122], [15, 123], [15, 124], [15, 125], [15, 126], [15, 127], [15, 128], [15, 129], [15, 130], [15, 131], [15, 132], [15, 133], [15, 134], [15, 135], [15, 136], [15, 137], [15, 138], [15, 139], [15, 140], [15, 141], [15, 142], [15, 143], [15, 144], [15, 145], [15, 151], [15, 152], [15, 153], [16, 1], [16, 2], [16, 3], [16, 4], [16, 18], [16, 19], [16, 20], [16, 23], [16, 24], [16, 25], [16, 26], [16, 28], [16, 29], [16, 30], [16, 31], [16, 32], [16, 33], [16, 34], [16, 35], [16, 36], [16, 37], [16, 38], [16, 39], [16, 40], [16, 62], [16, 63], [16, 64], [16, 65], [16, 73], [16, 74], [16, 79], [16, 80], [16, 109], [16, 110], [16, 111], [16, 112], [16, 123], [16, 124], [16, 125], [16, 126], [16, 127], [16, 128], [16, 129], [16, 130], [16, 131], [16, 132], [16, 133], [16, 134], [16, 135], [16, 136], [16, 137], [16, 138], [16, 139], [16, 140], [16, 141], [16, 142], [16, 143], [16, 144], [17, 7], [17, 8], [17, 17], [17, 18], [17, 22], [17, 23], [17, 24], [17, 25], [17, 26], [17, 27], [17, 28], [17, 29], [17, 30], [17, 31], [17, 32], [17, 33], [17, 34], [17, 35], [17, 36], [17, 37], [17, 38], [17, 39], [17, 40], [17, 49], [17, 50], [17, 55], [17, 61], [17, 62], [17, 63], [17, 64], [17, 65], [17, 69], [17, 70], [17, 71], [17, 72], [17, 79], [17, 80], [17, 81], [17, 82], [17, 107], [17, 108], [17, 110], [17, 111], [17, 115], [17, 116], [17, 124], [17, 125], [17, 126], [17, 127], [17, 128], [17, 129], [17, 130], [17, 131], [17, 132], [17, 133], [17, 134], [17, 135], [17, 136], [17, 137], [17, 138], [17, 139], [17, 140], [17, 141], [17, 142], [18, 0], [18, 1], [18, 2], [18, 14], [18, 15], [18, 16], [18, 17], [18, 18], [18, 19], [18, 20], [18, 21], [18, 22], [18, 23], [18, 24], [18, 25], [18, 26], [18, 27], [18, 28], [18, 29], [18, 30], [18, 31], [18, 32], [18, 33], [18, 34], [18, 35], [18, 36], [18, 37], [18, 38], [18, 39], [18, 49], [18, 50], [18, 53], [18, 54], [18, 58], [18, 59], [18, 63], [18, 64], [18, 65], [18, 66], [18, 68], [18, 69], [18, 70], [18, 71], [18, 102], [18, 103], [18, 104], [18, 105], [18, 106], [18, 107], [18, 108], [18, 109], [18, 110], [18, 115], [18, 116], [18, 125], [18, 126], [18, 127], [18, 128], [18, 129], [18, 130], [18, 131], [18, 132], [18, 133], [18, 134], [18, 135], [18, 136], [18, 137], [18, 138], [19, 1], [19, 2], [19, 3], [19, 14], [19, 15], [19, 16], [19, 17], [19, 18], [19, 19], [19, 20], [19, 21], [19, 22], [19, 24], [19, 25], [19, 26], [19, 27], [19, 28], [19, 29], [19, 30], [19, 31], [19, 32], [19, 33], [19, 34], [19, 35], [19, 36], [19, 37], [19, 38], [19, 48], [19, 49], [19, 50], [19, 51], [19, 52], [19, 53], [19, 54], [19, 55], [19, 56], [19, 57], [19, 61], [19, 62], [19, 63], [19, 64], [19, 65], [19, 66], [19, 67], [19, 68], [19, 69], [19, 70], [19, 80], [19, 81], [19, 82], [19, 108], [19, 111], [19, 112], [19, 113], [19, 114], [19, 115], [19, 116], [19, 117], [19, 118], [19, 119], [19, 127], [19, 128], [19, 129], [19, 130], [19, 131], [19, 132], [19, 133], [19, 134], [19, 135], [19, 136], [19, 137], [20, 0], [20, 1], [20, 2], [20, 5], [20, 6], [20, 7], [20, 8], [20, 13], [20, 14], [20, 15], [20, 17], [20, 18], [20, 19], [20, 20], [20, 21], [20, 22], [20, 23], [20, 24], [20, 25], [20, 26], [20, 27], [20, 28], [20, 29], [20, 30], [20, 31], [20, 32], [20, 33], [20, 34], [20, 47], [20, 48], [20, 49], [20, 50], [20, 51], [20, 52], [20, 53], [20, 56], [20, 57], [20, 58], [20, 62], [20, 63], [20, 64], [20, 65], [20, 66], [20, 67], [20, 68], [20, 69], [20, 74], [20, 75], [20, 80], [20, 81], [20, 99], [20, 100], [20, 101], [20, 102], [20, 107], [20, 108], [20, 109], [20, 110], [20, 111], [20, 112], [20, 113], [20, 114], [20, 115], [20, 116], [20, 117], [20, 118], [20, 119], [20, 122], [20, 123], [20, 128], [20, 129], [20, 130], [20, 131], [20, 132], [20, 133], [20, 134], [21, 2], [21, 3], [21, 4], [21, 5], [21, 6], [21, 7], [21, 12], [21, 13], [21, 14], [21, 15], [21, 17], [21, 18], [21, 19], [21, 20], [21, 21], [21, 22], [21, 26], [21, 27], [21, 28], [21, 29], [21, 30], [21, 31], [21, 32], [21, 45], [21, 46], [21, 47], [21, 48], [21, 49], [21, 50], [21, 51], [21, 52], [21, 53], [21, 54], [21, 55], [21, 56], [21, 57], [21, 58], [21, 59], [21, 60], [21, 61], [21, 62], [21, 63], [21, 64], [21, 65], [21, 66], [21, 67], [21, 68], [21, 69], [21, 70], [21, 71], [21, 72], [21, 75], [21, 76], [21, 80], [21, 81], [21, 82], [21, 96], [21, 97], [21, 98], [21, 99], [21, 100], [21, 101], [21, 102], [21, 103], [21, 110], [21, 111], [21, 112], [21, 113], [21, 114], [21, 115], [21, 116], [21, 117], [21, 118], [21, 149], [21, 150], [22, 1], [22, 2], [22, 3], [22, 4], [22, 5], [22, 6], [22, 7], [22, 10], [22, 11], [22, 12], [22, 13], [22, 14], [22, 15], [22, 19], [22, 20], [22, 21], [22, 22], [22, 23], [22, 25], [22, 26], [22, 27], [22, 28], [22, 29], [22, 30], [22, 31], [22, 44], [22, 45], [22, 46], [22, 47], [22, 48], [22, 49], [22, 50], [22, 51], [22, 52], [22, 53], [22, 54], [22, 55], [22, 57], [22, 59], [22, 60], [22, 61], [22, 62], [22, 63], [22, 64], [22, 65], [22, 66], [22, 67], [22, 68], [22, 69], [22, 70], [22, 71], [22, 72], [22, 73], [22, 74], [22, 96], [22, 97], [22, 98], [22, 99], [22, 100], [22, 101], [22, 111], [22, 112], [22, 113], [22, 114], [22, 115], [22, 116], [22, 117], [22, 128], [22, 129], [22, 130], [22, 150], [22, 151], [22, 152], [23, 0], [23, 1], [23, 2], [23, 3], [23, 4], [23, 5], [23, 6], [23, 7], [23, 11], [23, 12], [23, 13], [23, 14], [23, 15], [23, 16], [23, 19], [23, 20], [23, 21], [23, 22], [23, 23], [23, 24], [23, 25], [23, 26], [23, 27], [23, 29], [23, 42], [23, 43], [23, 44], [23, 45], [23, 46], [23, 47], [23, 48], [23, 49], [23, 50], [23, 51], [23, 52], [23, 53], [23, 56], [23, 57], [23, 58], [23, 61], [23, 62], [23, 63], [23, 64], [23, 65], [23, 66], [23, 67], [23, 68], [23, 72], [23, 73], [23, 74], [23, 75], [23, 76], [23, 88], [23, 89], [23, 90], [23, 112], [23, 113], [23, 114], [23, 115], [23, 116], [23, 128], [24, 0], [24, 1], [24, 2], [24, 3], [24, 4], [24, 5], [24, 6], [24, 11], [24, 12], [24, 13], [24, 14], [24, 19], [24, 20], [24, 21], [24, 22], [24, 23], [24, 24], [24, 25], [24, 26], [24, 27], [24, 28], [24, 29], [24, 39], [24, 41], [24, 42], [24, 43], [24, 49], [24, 50], [24, 51], [24, 55], [24, 56], [24, 57], [24, 58], [24, 59], [24, 60], [24, 61], [24, 62], [24, 63], [24, 64], [24, 65], [24, 66], [24, 67], [24, 72], [24, 73], [24, 74], [24, 87], [24, 88], [24, 89], [24, 91], [24, 92], [24, 93], [24, 100], [24, 101], [24, 105], [24, 106], [24, 107], [24, 108], [24, 121], [25, 13], [25, 14], [25, 15], [25, 16], [25, 17], [25, 18], [25, 19], [25, 20], [25, 21], [25, 22], [25, 23], [25, 24], [25, 25], [25, 26], [25, 27], [25, 28], [25, 33], [25, 34], [25, 35], [25, 36], [25, 37], [25, 38], [25, 39], [25, 40], [25, 41], [25, 42], [25, 43], [25, 44], [25, 51], [25, 52], [25, 53], [25, 54], [25, 55], [25, 56], [25, 57], [25, 58], [25, 59], [25, 60], [25, 61], [25, 62], [25, 63], [25, 64], [25, 65], [25, 66], [25, 67], [25, 68], [25, 69], [25, 70], [25, 71], [25, 72], [25, 73], [25, 74], [25, 75], [25, 76], [25, 77], [25, 78], [25, 81], [25, 82], [25, 86], [25, 87], [25, 88], [25, 100], [25, 110], [25, 111], [25, 112], [25, 113], [25, 118], [25, 127], [25, 128], [25, 129], [26, 1], [26, 13], [26, 14], [26, 15], [26, 16], [26, 19], [26, 20], [26, 21], [26, 22], [26, 23], [26, 24], [26, 25], [26, 26], [26, 27], [26, 28], [26, 29], [26, 31], [26, 32], [26, 33], [26, 34], [26, 35], [26, 36], [26, 37], [26, 38], [26, 39], [26, 40], [26, 41], [26, 52], [26, 53], [26, 54], [26, 55], [26, 56], [26, 57], [26, 58], [26, 59], [26, 60], [26, 61], [26, 62], [26, 63], [26, 64], [26, 65], [26, 66], [26, 67], [26, 68], [26, 69], [26, 70], [26, 71], [26, 72], [26, 73], [26, 74], [26, 75], [26, 76], [26, 77], [26, 78], [26, 79], [26, 80], [26, 81], [26, 82], [26, 83], [26, 84], [26, 85], [26, 87], [26, 88], [26, 89], [26, 101], [26, 107], [26, 112], [26, 113], [26, 126], [26, 127], [26, 128], [26, 129], [26, 130], [26, 131], [26, 146], [26, 147], [26, 149], [26, 150], [26, 151], [26, 152], [27, 0], [27, 1], [27, 2], [27, 3], [27, 4], [27, 11], [27, 12], [27, 13], [27, 14], [27, 15], [27, 16], [27, 17], [27, 18], [27, 19], [27, 20], [27, 21], [27, 22], [27, 23], [27, 24], [27, 25], [27, 26], [27, 27], [27, 28], [27, 29], [27, 30], [27, 31], [27, 32], [27, 33], [27, 34], [27, 35], [27, 36], [27, 37], [27, 38], [27, 39], [27, 40], [27, 49], [27, 50], [27, 51], [27, 52], [27, 53], [27, 54], [27, 55], [27, 56], [27, 57], [27, 58], [27, 59], [27, 60], [27, 61], [27, 62], [27, 63], [27, 64], [27, 65], [27, 66], [27, 67], [27, 68], [27, 69], [27, 70], [27, 71], [27, 72], [27, 73], [27, 74], [27, 75], [27, 76], [27, 77], [27, 78], [27, 79], [27, 80], [27, 81], [27, 82], [27, 83], [27, 84], [27, 85], [27, 86], [27, 87], [27, 88], [27, 89], [27, 105], [27, 106], [27, 107], [27, 108], [27, 110], [27, 129], [27, 130], [27, 131], [27, 132], [27, 145], [27, 146], [28, 0], [28, 1], [28, 2], [28, 3], [28, 4], [28, 5], [28, 6], [28, 7], [28, 8], [28, 9], [28, 10], [28, 14], [28, 15], [28, 16], [28, 17], [28, 18], [28, 19], [28, 20], [28, 21], [28, 22], [28, 23], [28, 24], [28, 25], [28, 26], [28, 27], [28, 28], [28, 29], [28, 30], [28, 37], [28, 39], [28, 48], [28, 49], [28, 50], [28, 51], [28, 52], [28, 53], [28, 54], [28, 55], [28, 56], [28, 57], [28, 63], [28, 64], [28, 65], [28, 66], [28, 67], [28, 68], [28, 69], [28, 70], [28, 71], [28, 72], [28, 73], [28, 74], [28, 75], [28, 76], [28, 77], [28, 78], [28, 79], [28, 80], [28, 81], [28, 82], [28, 83], [28, 84], [28, 85], [28, 86], [28, 87], [28, 88], [28, 89], [28, 90], [28, 99], [28, 100], [28, 101], [28, 102], [28, 103], [28, 104], [28, 105], [28, 106], [28, 130], [28, 131], [28, 132], [28, 133], [29, 0], [29, 1], [29, 2], [29, 3], [29, 4], [29, 5], [29, 6], [29, 7], [29, 8], [29, 9], [29, 10], [29, 11], [29, 12], [29, 13], [29, 14], [29, 15], [29, 16], [29, 17], [29, 18], [29, 19], [29, 20], [29, 21], [29, 22], [29, 23], [29, 24], [29, 25], [29, 26], [29, 29], [29, 30], [29, 31], [29, 33], [29, 34], [29, 35], [29, 36], [29, 37], [29, 38], [29, 39], [29, 48], [29, 49], [29, 50], [29, 51], [29, 52], [29, 53], [29, 54], [29, 55], [29, 56], [29, 57], [29, 58], [29, 59], [29, 60], [29, 61], [29, 62], [29, 63], [29, 64], [29, 67], [29, 68], [29, 69], [29, 70], [29, 71], [29, 74], [29, 75], [29, 76], [29, 77], [29, 78], [29, 79], [29, 80], [29, 81], [29, 82], [29, 83], [29, 84], [29, 85], [29, 86], [29, 87], [29, 88], [29, 97], [29, 98], [29, 99], [29, 100], [29, 105], [29, 106], [29, 107], [29, 108], [29, 127], [29, 128], [29, 129], [29, 130], [29, 131], [29, 132], [29, 133], [29, 134], [29, 143], [29, 144], [30, 0], [30, 1], [30, 2], [30, 3], [30, 4], [30, 5], [30, 6], [30, 7], [30, 8], [30, 13], [30, 14], [30, 15], [30, 16], [30, 17], [30, 18], [30, 19], [30, 20], [30, 21], [30, 22], [30, 23], [30, 24], [30, 25], [30, 26], [30, 27], [30, 28], [30, 29], [30, 30], [30, 31], [30, 32], [30, 33], [30, 34], [30, 35], [30, 36], [30, 37], [30, 38], [30, 39], [30, 40], [30, 41], [30, 42], [30, 43], [30, 44], [30, 45], [30, 46], [30, 47], [30, 48], [30, 49], [30, 50], [30, 51], [30, 52], [30, 53], [30, 54], [30, 55], [30, 56], [30, 57], [30, 58], [30, 59], [30, 60], [30, 61], [30, 64], [30, 65], [30, 66], [30, 67], [30, 68], [30, 69], [30, 70], [30, 71], [30, 74], [30, 75], [30, 76], [30, 77], [30, 78], [30, 79], [30, 80], [30, 81], [30, 82], [30, 83], [30, 84], [30, 85], [30, 91], [30, 92], [30, 97], [30, 98], [30, 99], [30, 105], [30, 106], [30, 117], [30, 122], [30, 126], [30, 127], [30, 128], [30, 129], [30, 130], [30, 131], [30, 132], [30, 143], [30, 144], [30, 145], [30, 146], [30, 150], [31, 0], [31, 1], [31, 2], [31, 3], [31, 4], [31, 5], [31, 6], [31, 7], [31, 8], [31, 9], [31, 14], [31, 15], [31, 16], [31, 17], [31, 18], [31, 19], [31, 20], [31, 21], [31, 22], [31, 23], [31, 24], [31, 25], [31, 26], [31, 27], [31, 28], [31, 29], [31, 30], [31, 33], [31, 34], [31, 35], [31, 36], [31, 37], [31, 40], [31, 41], [31, 42], [31, 43], [31, 44], [31, 45], [31, 46], [31, 47], [31, 48], [31, 49], [31, 50], [31, 51], [31, 52], [31, 53], [31, 54], [31, 55], [31, 56], [31, 57], [31, 58], [31, 59], [31, 60], [31, 61], [31, 62], [31, 63], [31, 64], [31, 65], [31, 66], [31, 67], [31, 68], [31, 69], [31, 70], [31, 71], [31, 72], [31, 73], [31, 74], [31, 75], [31, 78], [31, 79], [31, 80], [31, 81], [31, 82], [31, 84], [31, 94], [31, 95], [31, 96], [31, 97], [31, 98], [31, 116], [31, 117], [31, 129], [31, 130], [31, 131], [31, 132], [31, 133], [31, 134], [31, 143], [31, 144], [31, 145], [31, 146], [32, 1], [32, 2], [32, 3], [32, 4], [32, 5], [32, 6], [32, 7], [32, 8], [32, 9], [32, 14], [32, 15], [32, 16], [32, 17], [32, 18], [32, 19], [32, 20], [32, 21], [32, 22], [32, 23], [32, 24], [32, 25], [32, 28], [32, 29], [32, 30], [32, 31], [32, 32], [32, 33], [32, 34], [32, 35], [32, 36], [32, 37], [32, 38], [32, 42], [32, 43], [32, 44], [32, 45], [32, 46], [32, 47], [32, 48], [32, 49], [32, 50], [32, 51], [32, 52], [32, 53], [32, 54], [32, 56], [32, 57], [32, 58], [32, 59], [32, 60], [32, 61], [32, 65], [32, 66], [32, 67], [32, 68], [32, 69], [32, 74], [32, 75], [32, 76], [32, 77], [32, 78], [32, 79], [32, 80], [32, 81], [32, 82], [32, 83], [32, 84], [32, 85], [32, 89], [32, 90], [32, 91], [32, 92], [32, 96], [32, 97], [32, 98], [32, 99], [32, 100], [32, 124], [32, 125], [32, 126], [32, 130], [32, 131], [32, 132], [32, 143], [32, 144], [33, 0], [33, 1], [33, 2], [33, 3], [33, 4], [33, 5], [33, 6], [33, 8], [33, 9], [33, 10], [33, 11], [33, 12], [33, 13], [33, 14], [33, 15], [33, 16], [33, 17], [33, 18], [33, 19], [33, 20], [33, 21], [33, 22], [33, 23], [33, 24], [33, 25], [33, 26], [33, 27], [33, 28], [33, 29], [33, 30], [33, 31], [33, 32], [33, 33], [33, 34], [33, 35], [33, 36], [33, 37], [33, 38], [33, 39], [33, 46], [33, 47], [33, 48], [33, 49], [33, 50], [33, 51], [33, 52], [33, 53], [33, 60], [33, 61], [33, 62], [33, 63], [33, 64], [33, 65], [33, 66], [33, 67], [33, 68], [33, 69], [33, 70], [33, 73], [33, 74], [33, 75], [33, 76], [33, 77], [33, 78], [33, 79], [33, 80], [33, 81], [33, 82], [33, 83], [33, 84], [33, 85], [33, 86], [33, 87], [33, 88], [33, 89], [33, 102], [33, 103], [33, 104], [33, 105], [33, 109], [33, 110], [33, 123], [33, 124], [33, 131], [33, 132], [33, 142], [33, 143], [33, 144], [33, 145], [33, 146], [33, 163], [34, 0], [34, 1], [34, 2], [34, 3], [34, 4], [34, 5], [34, 6], [34, 7], [34, 8], [34, 9], [34, 10], [34, 11], [34, 12], [34, 13], [34, 14], [34, 15], [34, 16], [34, 17], [34, 18], [34, 19], [34, 20], [34, 21], [34, 22], [34, 23], [34, 24], [34, 25], [34, 26], [34, 27], [34, 28], [34, 29], [34, 30], [34, 31], [34, 34], [34, 35], [34, 36], [34, 37], [34, 38], [34, 45], [34, 46], [34, 47], [34, 48], [34, 49], [34, 50], [34, 51], [34, 52], [34, 53], [34, 63], [34, 64], [34, 65], [34, 66], [34, 67], [34, 68], [34, 69], [34, 70], [34, 71], [34, 72], [34, 73], [34, 74], [34, 75], [34, 76], [34, 77], [34, 86], [34, 90], [34, 91], [34, 92], [34, 93], [34, 94], [34, 95], [34, 96], [34, 97], [34, 101], [34, 102], [34, 116], [34, 117], [34, 118], [34, 122], [34, 123], [34, 124], [34, 125], [34, 130], [34, 131], [34, 132], [34, 133], [34, 134], [34, 135], [34, 142], [34, 143], [34, 144], [34, 145], [34, 146], [35, 0], [35, 1], [35, 2], [35, 3], [35, 4], [35, 5], [35, 6], [35, 7], [35, 8], [35, 9], [35, 10], [35, 11], [35, 12], [35, 13], [35, 14], [35, 15], [35, 16], [35, 17], [35, 18], [35, 19], [35, 20], [35, 21], [35, 22], [35, 23], [35, 24], [35, 25], [35, 26], [35, 27], [35, 28], [35, 29], [35, 30], [35, 31], [35, 32], [35, 33], [35, 34], [35, 35], [35, 36], [35, 37], [35, 38], [35, 39], [35, 53], [35, 54], [35, 55], [35, 56], [35, 57], [35, 58], [35, 60], [35, 61], [35, 62], [35, 63], [35, 64], [35, 65], [35, 66], [35, 67], [35, 68], [35, 69], [35, 70], [35, 71], [35, 72], [35, 73], [35, 74], [35, 75], [35, 76], [35, 77], [35, 78], [35, 82], [35, 83], [35, 84], [35, 85], [35, 92], [35, 93], [35, 94], [35, 95], [35, 96], [35, 97], [35, 98], [35, 99], [35, 100], [35, 101], [35, 121], [35, 122], [35, 123], [35, 129], [35, 130], [35, 131], [35, 132], [35, 133], [35, 134], [35, 135], [36, 0], [36, 1], [36, 2], [36, 3], [36, 4], [36, 5], [36, 6], [36, 7], [36, 8], [36, 9], [36, 10], [36, 11], [36, 12], [36, 13], [36, 14], [36, 15], [36, 16], [36, 17], [36, 18], [36, 19], [36, 20], [36, 21], [36, 22], [36, 23], [36, 24], [36, 30], [36, 31], [36, 32], [36, 33], [36, 34], [36, 35], [36, 36], [36, 37], [36, 38], [36, 39], [36, 40], [36, 41], [36, 42], [36, 43], [36, 44], [36, 45], [36, 53], [36, 54], [36, 55], [36, 56], [36, 57], [36, 58], [36, 59], [36, 60], [36, 61], [36, 62], [36, 63], [36, 64], [36, 67], [36, 68], [36, 69], [36, 70], [36, 71], [36, 72], [36, 73], [36, 74], [36, 75], [36, 76], [36, 77], [36, 78], [36, 89], [36, 90], [36, 91], [36, 93], [36, 94], [36, 95], [36, 96], [36, 97], [36, 98], [36, 99], [36, 100], [36, 101], [36, 102], [36, 110], [36, 111], [36, 112], [36, 113], [36, 114], [36, 115], [36, 121], [36, 127], [36, 128], [36, 129], [36, 130], [36, 131], [36, 132], [37, 1], [37, 2], [37, 3], [37, 4], [37, 5], [37, 6], [37, 7], [37, 8], [37, 9], [37, 10], [37, 11], [37, 12], [37, 13], [37, 14], [37, 15], [37, 16], [37, 17], [37, 18], [37, 19], [37, 20], [37, 21], [37, 22], [37, 23], [37, 24], [37, 25], [37, 26], [37, 34], [37, 35], [37, 36], [37, 37], [37, 38], [37, 39], [37, 41], [37, 42], [37, 43], [37, 44], [37, 45], [37, 46], [37, 47], [37, 63], [37, 64], [37, 65], [37, 66], [37, 67], [37, 68], [37, 69], [37, 70], [37, 71], [37, 72], [37, 73], [37, 74], [37, 75], [37, 76], [37, 77], [37, 78], [37, 89], [37, 90], [37, 91], [37, 92], [37, 93], [37, 98], [37, 101], [37, 102], [37, 103], [37, 104], [37, 109], [37, 110], [37, 111], [37, 112], [37, 113], [37, 114], [37, 115], [37, 116], [37, 118], [37, 119], [37, 120], [37, 121], [37, 125], [37, 126], [37, 127], [37, 128], [37, 129], [37, 130], [37, 131], [37, 132], [37, 133], [37, 134], [37, 135], [37, 142], [37, 143], [37, 144], [37, 145], [37, 146], [37, 150], [37, 151], [38, 4], [38, 5], [38, 6], [38, 7], [38, 8], [38, 9], [38, 10], [38, 11], [38, 12], [38, 13], [38, 14], [38, 15], [38, 16], [38, 17], [38, 18], [38, 19], [38, 20], [38, 21], [38, 22], [38, 23], [38, 24], [38, 25], [38, 26], [38, 36], [38, 37], [38, 44], [38, 45], [38, 46], [38, 47], [38, 48], [38, 51], [38, 52], [38, 53], [38, 54], [38, 55], [38, 56], [38, 57], [38, 58], [38, 59], [38, 60], [38, 61], [38, 62], [38, 63], [38, 64], [38, 65], [38, 66], [38, 67], [38, 68], [38, 69], [38, 70], [38, 71], [38, 72], [38, 73], [38, 76], [38, 77], [38, 78], [38, 79], [38, 80], [38, 81], [38, 83], [38, 84], [38, 85], [38, 88], [38, 89], [38, 90], [38, 91], [38, 92], [38, 99], [38, 100], [38, 101], [38, 102], [38, 103], [38, 104], [38, 105], [38, 121], [38, 127], [38, 128], [38, 129], [38, 130], [38, 131], [38, 132], [38, 133], [38, 142], [38, 143], [38, 144], [38, 145], [38, 146], [38, 147], [38, 148], [38, 149], [39, 0], [39, 1], [39, 2], [39, 3], [39, 4], [39, 5], [39, 6], [39, 7], [39, 8], [39, 9], [39, 10], [39, 11], [39, 12], [39, 13], [39, 14], [39, 15], [39, 16], [39, 17], [39, 18], [39, 19], [39, 22], [39, 23], [39, 24], [39, 25], [39, 26], [39, 50], [39, 51], [39, 52], [39, 53], [39, 54], [39, 55], [39, 56], [39, 60], [39, 61], [39, 62], [39, 63], [39, 64], [39, 65], [39, 66], [39, 67], [39, 68], [39, 69], [39, 70], [39, 71], [39, 72], [39, 73], [39, 74], [39, 75], [39, 76], [39, 77], [39, 78], [39, 79], [39, 80], [39, 81], [39, 82], [39, 83], [39, 84], [39, 85], [39, 87], [39, 93], [39, 94], [39, 95], [39, 96], [39, 97], [39, 100], [39, 101], [39, 102], [39, 103], [39, 104], [39, 114], [39, 115], [39, 122], [39, 123], [39, 124], [39, 125], [39, 126], [39, 127], [39, 129], [39, 130], [39, 131], [39, 132], [39, 133], [39, 134], [39, 135], [39, 136], [39, 137], [39, 143], [39, 144], [39, 145], [39, 146], [39, 147], [39, 148], [39, 149], [40, 4], [40, 5], [40, 6], [40, 7], [40, 8], [40, 9], [40, 10], [40, 11], [40, 12], [40, 13], [40, 14], [40, 15], [40, 16], [40, 17], [40, 18], [40, 19], [40, 20], [40, 21], [40, 22], [40, 25], [40, 26], [40, 27], [40, 28], [40, 46], [40, 47], [40, 48], [40, 49], [40, 50], [40, 60], [40, 61], [40, 62], [40, 63], [40, 64], [40, 65], [40, 66], [40, 67], [40, 68], [40, 69], [40, 70], [40, 71], [40, 72], [40, 73], [40, 74], [40, 75], [40, 78], [40, 79], [40, 80], [40, 81], [40, 82], [40, 83], [40, 84], [40, 85], [40, 86], [40, 90], [40, 91], [40, 92], [40, 93], [40, 94], [40, 95], [40, 98], [40, 99], [40, 100], [40, 101], [40, 102], [40, 103], [40, 104], [40, 105], [40, 106], [40, 113], [40, 114], [40, 115], [40, 116], [40, 122], [40, 123], [40, 124], [40, 125], [40, 126], [40, 127], [40, 128], [40, 129], [40, 132], [40, 133], [40, 134], [40, 135], [40, 136], [40, 137], [40, 143], [40, 144], [40, 145], [40, 146], [40, 147], [41, 14], [41, 15], [41, 16], [41, 17], [41, 18], [41, 19], [41, 20], [41, 21], [41, 24], [41, 25], [41, 26], [41, 27], [41, 28], [41, 45], [41, 46], [41, 47], [41, 48], [41, 49], [41, 53], [41, 54], [41, 57], [41, 58], [41, 59], [41, 60], [41, 61], [41, 62], [41, 63], [41, 64], [41, 65], [41, 66], [41, 67], [41, 68], [41, 69], [41, 70], [41, 71], [41, 72], [41, 73], [41, 74], [41, 75], [41, 76], [41, 77], [41, 78], [41, 79], [41, 80], [41, 81], [41, 82], [41, 83], [41, 84], [41, 89], [41, 90], [41, 91], [41, 92], [41, 93], [41, 96], [41, 97], [41, 98], [41, 99], [41, 100], [41, 101], [41, 102], [41, 105], [41, 106], [41, 107], [41, 113], [41, 114], [41, 115], [41, 119], [41, 120], [41, 121], [41, 122], [41, 123], [41, 124], [41, 133], [41, 134], [41, 135], [41, 136], [41, 142], [41, 143], [41, 144], [41, 145], [41, 153], [41, 154], [41, 155], [41, 156], [42, 15], [42, 16], [42, 17], [42, 18], [42, 19], [42, 20], [42, 21], [42, 22], [42, 23], [42, 24], [42, 25], [42, 26], [42, 49], [42, 50], [42, 51], [42, 52], [42, 54], [42, 55], [42, 56], [42, 57], [42, 58], [42, 59], [42, 60], [42, 61], [42, 62], [42, 63], [42, 64], [42, 65], [42, 66], [42, 67], [42, 68], [42, 69], [42, 75], [42, 76], [42, 77], [42, 78], [42, 79], [42, 80], [42, 81], [42, 82], [42, 83], [42, 89], [42, 90], [42, 91], [42, 92], [42, 93], [42, 95], [42, 96], [42, 97], [42, 98], [42, 99], [42, 100], [42, 101], [42, 102], [42, 103], [42, 104], [42, 113], [42, 114], [42, 115], [42, 116], [42, 117], [42, 118], [42, 119], [42, 130], [42, 131], [42, 132], [42, 133], [42, 134], [42, 135], [42, 136], [42, 145], [42, 146], [42, 151], [42, 152], [42, 153], [43, 16], [43, 17], [43, 18], [43, 19], [43, 23], [43, 27], [43, 45], [43, 46], [43, 54], [43, 55], [43, 56], [43, 57], [43, 58], [43, 59], [43, 60], [43, 61], [43, 62], [43, 63], [43, 64], [43, 65], [43, 66], [43, 67], [43, 68], [43, 69], [43, 76], [43, 77], [43, 78], [43, 79], [43, 80], [43, 81], [43, 82], [43, 83], [43, 85], [43, 86], [43, 87], [43, 88], [43, 89], [43, 90], [43, 91], [43, 92], [43, 93], [43, 94], [43, 95], [43, 96], [43, 97], [43, 98], [43, 99], [43, 100], [43, 101], [43, 102], [43, 103], [43, 104], [43, 105], [43, 106], [43, 110], [43, 111], [43, 115], [43, 116], [43, 117], [43, 130], [43, 131], [43, 132], [43, 133], [43, 134], [43, 135], [43, 136], [43, 143], [43, 144], [43, 145], [43, 146], [43, 147], [43, 150], [43, 151], [44, 15], [44, 16], [44, 17], [44, 18], [44, 19], [44, 20], [44, 23], [44, 24], [44, 25], [44, 26], [44, 27], [44, 28], [44, 29], [44, 44], [44, 45], [44, 46], [44, 49], [44, 50], [44, 59], [44, 60], [44, 61], [44, 62], [44, 63], [44, 64], [44, 65], [44, 66], [44, 67], [44, 68], [44, 69], [44, 74], [44, 75], [44, 76], [44, 77], [44, 78], [44, 79], [44, 80], [44, 81], [44, 84], [44, 85], [44, 86], [44, 87], [44, 90], [44, 91], [44, 92], [44, 93], [44, 94], [44, 95], [44, 96], [44, 97], [44, 98], [44, 101], [44, 102], [44, 103], [44, 109], [44, 110], [44, 111], [44, 115], [44, 116], [44, 117], [44, 127], [44, 128], [44, 129], [44, 130], [44, 131], [44, 132], [44, 133], [44, 134], [44, 135], [44, 136], [44, 144], [44, 145], [44, 146], [44, 147], [44, 148], [44, 149], [44, 150], [44, 151], [44, 152], [45, 16], [45, 17], [45, 18], [45, 19], [45, 20], [45, 21], [45, 26], [45, 27], [45, 31], [45, 32], [45, 33], [45, 34], [45, 36], [45, 37], [45, 38], [45, 39], [45, 40], [45, 41], [45, 42], [45, 43], [45, 44], [45, 45], [45, 48], [45, 49], [45, 50], [45, 51], [45, 52], [45, 55], [45, 56], [45, 57], [45, 58], [45, 59], [45, 60], [45, 61], [45, 62], [45, 63], [45, 66], [45, 67], [45, 68], [45, 69], [45, 70], [45, 71], [45, 72], [45, 73], [45, 74], [45, 75], [45, 76], [45, 77], [45, 78], [45, 79], [45, 80], [45, 81], [45, 82], [45, 83], [45, 84], [45, 85], [45, 86], [45, 87], [45, 88], [45, 89], [45, 90], [45, 91], [45, 92], [45, 93], [45, 94], [45, 95], [45, 96], [45, 97], [45, 98], [45, 99], [45, 100], [45, 101], [45, 102], [45, 103], [45, 104], [45, 109], [45, 110], [45, 111], [45, 112], [45, 113], [45, 114], [45, 115], [45, 116], [45, 117], [45, 118], [45, 119], [45, 131], [45, 132], [45, 133], [45, 135], [45, 136], [45, 137], [45, 143], [45, 144], [45, 145], [45, 146], [45, 147], [45, 148], [45, 155], [45, 156], [46, 1], [46, 14], [46, 15], [46, 16], [46, 17], [46, 18], [46, 19], [46, 20], [46, 21], [46, 22], [46, 23], [46, 24], [46, 25], [46, 26], [46, 27], [46, 28], [46, 29], [46, 30], [46, 31], [46, 32], [46, 36], [46, 37], [46, 38], [46, 39], [46, 40], [46, 41], [46, 56], [46, 57], [46, 58], [46, 59], [46, 64], [46, 65], [46, 66], [46, 67], [46, 68], [46, 69], [46, 70], [46, 74], [46, 75], [46, 76], [46, 77], [46, 78], [46, 81], [46, 82], [46, 85], [46, 86], [46, 87], [46, 88], [46, 89], [46, 93], [46, 94], [46, 95], [46, 96], [46, 97], [46, 98], [46, 99], [46, 100], [46, 133], [46, 134], [46, 135], [46, 136], [46, 137], [46, 144], [46, 145], [46, 146], [46, 149], [46, 150], [46, 151], [46, 152], [47, 0], [47, 1], [47, 2], [47, 14], [47, 15], [47, 16], [47, 17], [47, 18], [47, 19], [47, 20], [47, 27], [47, 28], [47, 34], [47, 35], [47, 36], [47, 43], [47, 44], [47, 45], [47, 46], [47, 47], [47, 48], [47, 49], [47, 50], [47, 56], [47, 57], [47, 64], [47, 65], [47, 66], [47, 67], [47, 68], [47, 69], [47, 70], [47, 76], [47, 77], [47, 78], [47, 79], [47, 80], [47, 81], [47, 82], [47, 84], [47, 85], [47, 86], [47, 87], [47, 88], [47, 89], [47, 90], [47, 91], [47, 92], [47, 93], [47, 94], [47, 95], [47, 96], [47, 99], [47, 100], [47, 101], [47, 102], [47, 103], [47, 104], [47, 105], [47, 106], [47, 113], [47, 116], [47, 131], [47, 132], [47, 133], [47, 134], [47, 135], [47, 136], [47, 137], [47, 145], [47, 146], [48, 0], [48, 1], [48, 13], [48, 14], [48, 17], [48, 18], [48, 19], [48, 20], [48, 21], [48, 22], [48, 23], [48, 34], [48, 35], [48, 36], [48, 37], [48, 38], [48, 39], [48, 40], [48, 43], [48, 44], [48, 45], [48, 46], [48, 47], [48, 48], [48, 49], [48, 54], [48, 55], [48, 56], [48, 57], [48, 60], [48, 61], [48, 62], [48, 63], [48, 67], [48, 69], [48, 70], [48, 71], [48, 72], [48, 73], [48, 77], [48, 79], [48, 80], [48, 81], [48, 82], [48, 83], [48, 84], [48, 85], [48, 86], [48, 87], [48, 88], [48, 89], [48, 90], [48, 91], [48, 92], [48, 93], [48, 94], [48, 95], [48, 96], [48, 97], [48, 98], [48, 99], [48, 100], [48, 103], [48, 104], [48, 111], [48, 117], [48, 118], [48, 131], [48, 132], [48, 133], [48, 134], [48, 135], [49, 13], [49, 14], [49, 15], [49, 16], [49, 17], [49, 18], [49, 19], [49, 20], [49, 21], [49, 22], [49, 23], [49, 24], [49, 34], [49, 35], [49, 36], [49, 37], [49, 38], [49, 39], [49, 40], [49, 41], [49, 42], [49, 43], [49, 44], [49, 45], [49, 46], [49, 56], [49, 57], [49, 58], [49, 59], [49, 60], [49, 61], [49, 62], [49, 63], [49, 64], [49, 65], [49, 66], [49, 67], [49, 68], [49, 69], [49, 70], [49, 71], [49, 72], [49, 73], [49, 74], [49, 75], [49, 76], [49, 77], [49, 78], [49, 79], [49, 80], [49, 81], [49, 82], [49, 83], [49, 84], [49, 85], [49, 86], [49, 87], [49, 88], [49, 89], [49, 90], [49, 91], [49, 92], [49, 95], [49, 96], [49, 102], [49, 103], [49, 104], [49, 105], [49, 106], [49, 111], [49, 131], [49, 132], [49, 133], [49, 134], [49, 135], [50, 0], [50, 1], [50, 14], [50, 15], [50, 17], [50, 18], [50, 19], [50, 20], [50, 21], [50, 34], [50, 35], [50, 36], [50, 37], [50, 41], [50, 42], [50, 43], [50, 44], [50, 49], [50, 50], [50, 51], [50, 52], [50, 53], [50, 54], [50, 55], [50, 56], [50, 57], [50, 58], [50, 59], [50, 60], [50, 65], [50, 66], [50, 68], [50, 69], [50, 70], [50, 71], [50, 72], [50, 73], [50, 74], [50, 75], [50, 76], [50, 77], [50, 78], [50, 82], [50, 83], [50, 84], [50, 85], [50, 86], [50, 87], [50, 88], [50, 89], [50, 90], [50, 91], [50, 92], [50, 93], [50, 94], [50, 95], [50, 96], [50, 97], [50, 98], [50, 99], [50, 100], [50, 101], [50, 102], [50, 103], [50, 104], [50, 105], [50, 106], [50, 107], [50, 108], [50, 109], [50, 110], [50, 111], [50, 118], [50, 119], [50, 120], [50, 121], [50, 122], [50, 129], [50, 130], [51, 1], [51, 2], [51, 3], [51, 12], [51, 13], [51, 14], [51, 15], [51, 34], [51, 35], [51, 36], [51, 50], [51, 51], [51, 52], [51, 53], [51, 54], [51, 55], [51, 68], [51, 69], [51, 70], [51, 71], [51, 72], [51, 73], [51, 74], [51, 75], [51, 76], [51, 77], [51, 78], [51, 79], [51, 80], [51, 81], [51, 82], [51, 83], [51, 84], [51, 85], [51, 86], [51, 87], [51, 88], [51, 89], [51, 93], [51, 94], [51, 95], [51, 96], [51, 97], [51, 98], [51, 99], [51, 100], [51, 101], [51, 102], [51, 103], [51, 104], [51, 105], [51, 106], [51, 111], [51, 112], [51, 113], [51, 114], [51, 115], [51, 116], [51, 132], [51, 133], [51, 134], [51, 135], [51, 136], [51, 137], [51, 138], [52, 0], [52, 1], [52, 12], [52, 13], [52, 14], [52, 15], [52, 16], [52, 17], [52, 18], [52, 19], [52, 33], [52, 34], [52, 35], [52, 38], [52, 39], [52, 46], [52, 47], [52, 48], [52, 49], [52, 50], [52, 54], [52, 55], [52, 56], [52, 57], [52, 58], [52, 64], [52, 65], [52, 66], [52, 68], [52, 70], [52, 71], [52, 72], [52, 73], [52, 74], [52, 75], [52, 76], [52, 77], [52, 78], [52, 79], [52, 80], [52, 81], [52, 82], [52, 83], [52, 84], [52, 85], [52, 86], [52, 87], [52, 88], [52, 89], [52, 90], [52, 91], [52, 92], [52, 93], [52, 94], [52, 95], [52, 96], [52, 97], [52, 98], [52, 103], [52, 104], [52, 105], [52, 111], [52, 112], [52, 115], [52, 116], [52, 117], [52, 121], [52, 122], [52, 123], [52, 124], [52, 125], [52, 133], [52, 134], [52, 135], [52, 136], [52, 137], [52, 146], [52, 147], [52, 148], [53, 0], [53, 1], [53, 12], [53, 13], [53, 14], [53, 15], [53, 16], [53, 17], [53, 25], [53, 30], [53, 31], [53, 32], [53, 47], [53, 48], [53, 49], [53, 50], [53, 51], [53, 52], [53, 53], [53, 54], [53, 55], [53, 56], [53, 57], [53, 58], [53, 59], [53, 60], [53, 61], [53, 62], [53, 63], [53, 64], [53, 65], [53, 66], [53, 67], [53, 68], [53, 69], [53, 70], [53, 75], [53, 76], [53, 77], [53, 78], [53, 79], [53, 80], [53, 81], [53, 84], [53, 85], [53, 86], [53, 87], [53, 88], [53, 89], [53, 90], [53, 91], [53, 92], [53, 93], [53, 94], [53, 95], [53, 96], [53, 97], [53, 98], [53, 99], [53, 108], [53, 109], [53, 110], [53, 111], [53, 112], [53, 123], [53, 124], [53, 125], [53, 126], [53, 127], [53, 132], [53, 133], [53, 134], [53, 135], [53, 136], [54, 0], [54, 1], [54, 3], [54, 12], [54, 13], [54, 14], [54, 15], [54, 16], [54, 17], [54, 40], [54, 41], [54, 42], [54, 49], [54, 50], [54, 51], [54, 52], [54, 53], [54, 54], [54, 55], [54, 56], [54, 60], [54, 61], [54, 65], [54, 66], [54, 67], [54, 68], [54, 69], [54, 70], [54, 71], [54, 76], [54, 77], [54, 78], [54, 79], [54, 80], [54, 81], [54, 82], [54, 88], [54, 89], [54, 90], [54, 91], [54, 92], [54, 93], [54, 94], [54, 95], [54, 96], [54, 97], [54, 98], [54, 99], [54, 100], [54, 101], [54, 104], [54, 105], [54, 106], [54, 107], [54, 108], [54, 125], [54, 126], [54, 130], [54, 131], [54, 132], [54, 133], [54, 134], [54, 135], [54, 136], [54, 137], [54, 138], [55, 3], [55, 4], [55, 5], [55, 12], [55, 13], [55, 14], [55, 15], [55, 18], [55, 19], [55, 20], [55, 21], [55, 22], [55, 23], [55, 24], [55, 25], [55, 29], [55, 30], [55, 31], [55, 32], [55, 33], [55, 34], [55, 35], [55, 36], [55, 37], [55, 38], [55, 40], [55, 42], [55, 43], [55, 44], [55, 45], [55, 46], [55, 47], [55, 48], [55, 50], [55, 51], [55, 52], [55, 53], [55, 54], [55, 55], [55, 56], [55, 58], [55, 59], [55, 60], [55, 63], [55, 64], [55, 65], [55, 66], [55, 67], [55, 68], [55, 69], [55, 70], [55, 71], [55, 72], [55, 73], [55, 74], [55, 75], [55, 76], [55, 77], [55, 78], [55, 79], [55, 80], [55, 81], [55, 82], [55, 88], [55, 89], [55, 90], [55, 91], [55, 92], [55, 93], [55, 94], [55, 95], [55, 96], [55, 100], [55, 101], [55, 102], [55, 103], [55, 113], [55, 114], [55, 115], [55, 116], [55, 117], [55, 131], [55, 132], [55, 133], [55, 134], [55, 135], [55, 136], [55, 137], [55, 138], [56, 0], [56, 1], [56, 2], [56, 3], [56, 4], [56, 5], [56, 13], [56, 14], [56, 15], [56, 19], [56, 27], [56, 28], [56, 29], [56, 30], [56, 31], [56, 36], [56, 37], [56, 38], [56, 39], [56, 40], [56, 41], [56, 42], [56, 44], [56, 45], [56, 46], [56, 49], [56, 50], [56, 51], [56, 53], [56, 54], [56, 55], [56, 59], [56, 60], [56, 61], [56, 62], [56, 63], [56, 64], [56, 65], [56, 66], [56, 67], [56, 68], [56, 69], [56, 72], [56, 73], [56, 74], [56, 75], [56, 76], [56, 77], [56, 78], [56, 79], [56, 80], [56, 81], [56, 82], [56, 83], [56, 84], [56, 85], [56, 86], [56, 87], [56, 88], [56, 89], [56, 92], [56, 93], [56, 94], [56, 113], [56, 114], [56, 115], [56, 116], [56, 133], [56, 134], [56, 135], [56, 136], [56, 137], [56, 138], [57, 0], [57, 1], [57, 2], [57, 3], [57, 4], [57, 12], [57, 13], [57, 14], [57, 15], [57, 16], [57, 17], [57, 18], [57, 19], [57, 20], [57, 21], [57, 25], [57, 26], [57, 27], [57, 28], [57, 29], [57, 30], [57, 31], [57, 35], [57, 36], [57, 37], [57, 42], [57, 43], [57, 44], [57, 45], [57, 48], [57, 49], [57, 50], [57, 51], [57, 52], [57, 53], [57, 54], [57, 55], [57, 56], [57, 57], [57, 58], [57, 59], [57, 60], [57, 61], [57, 62], [57, 63], [57, 64], [57, 65], [57, 66], [57, 67], [57, 68], [57, 69], [57, 70], [57, 72], [57, 76], [57, 78], [57, 79], [57, 80], [57, 81], [57, 82], [57, 83], [57, 84], [57, 85], [57, 86], [57, 87], [57, 88], [57, 89], [57, 90], [57, 91], [57, 92], [57, 93], [57, 94], [57, 95], [57, 96], [57, 97], [57, 98], [57, 99], [57, 100], [57, 101], [57, 102], [57, 103], [57, 120], [57, 121], [57, 122], [57, 130], [57, 131], [57, 132], [57, 133], [57, 134], [57, 135], [57, 136], [58, 4], [58, 5], [58, 12], [58, 13], [58, 14], [58, 15], [58, 16], [58, 17], [58, 18], [58, 19], [58, 22], [58, 23], [58, 24], [58, 25], [58, 26], [58, 27], [58, 28], [58, 29], [58, 31], [58, 40], [58, 41], [58, 42], [58, 43], [58, 44], [58, 53], [58, 54], [58, 55], [58, 56], [58, 57], [58, 58], [58, 59], [58, 63], [58, 64], [58, 65], [58, 66], [58, 67], [58, 68], [58, 69], [58, 72], [58, 73], [58, 74], [58, 75], [58, 76], [58, 77], [58, 78], [58, 79], [58, 80], [58, 81], [58, 85], [58, 86], [58, 87], [58, 90], [58, 97], [58, 98], [58, 99], [58, 100], [58, 103], [58, 104], [58, 105], [58, 106], [58, 107], [58, 111], [58, 112], [58, 113], [58, 114], [58, 115], [58, 121], [58, 122], [58, 123], [58, 124], [58, 125], [58, 126], [58, 130], [58, 131], [58, 132], [58, 133], [58, 134], [58, 135], [58, 136], [58, 137], [58, 138], [58, 146], [59, 13], [59, 14], [59, 15], [59, 16], [59, 17], [59, 18], [59, 23], [59, 24], [59, 25], [59, 26], [59, 27], [59, 28], [59, 29], [59, 30], [59, 40], [59, 41], [59, 42], [59, 43], [59, 44], [59, 45], [59, 46], [59, 47], [59, 48], [59, 49], [59, 50], [59, 51], [59, 52], [59, 53], [59, 54], [59, 55], [59, 58], [59, 59], [59, 60], [59, 61], [59, 62], [59, 63], [59, 64], [59, 65], [59, 66], [59, 67], [59, 68], [59, 69], [59, 73], [59, 74], [59, 75], [59, 76], [59, 80], [59, 85], [59, 86], [59, 87], [59, 88], [59, 89], [59, 90], [59, 91], [59, 92], [59, 97], [59, 98], [59, 99], [59, 100], [59, 101], [59, 102], [59, 113], [59, 114], [59, 115], [59, 123], [59, 124], [59, 125], [59, 128], [59, 129], [59, 130], [59, 131], [59, 132], [59, 133], [59, 134], [59, 135], [59, 136], [59, 137], [60, 0], [60, 1], [60, 2], [60, 3], [60, 4], [60, 5], [60, 6], [60, 14], [60, 15], [60, 16], [60, 17], [60, 18], [60, 19], [60, 20], [60, 21], [60, 22], [60, 23], [60, 24], [60, 25], [60, 26], [60, 27], [60, 39], [60, 40], [60, 41], [60, 42], [60, 43], [60, 44], [60, 45], [60, 46], [60, 47], [60, 48], [60, 49], [60, 50], [60, 51], [60, 52], [60, 61], [60, 62], [60, 63], [60, 64], [60, 65], [60, 66], [60, 67], [60, 68], [60, 70], [60, 72], [60, 73], [60, 74], [60, 75], [60, 76], [60, 77], [60, 78], [60, 79], [60, 80], [60, 89], [60, 90], [60, 91], [60, 92], [60, 93], [60, 97], [60, 98], [60, 99], [60, 100], [60, 101], [60, 102], [60, 122], [60, 123], [60, 128], [60, 129], [60, 135], [61, 4], [61, 5], [61, 6], [61, 15], [61, 16], [61, 17], [61, 18], [61, 19], [61, 20], [61, 21], [61, 22], [61, 23], [61, 24], [61, 25], [61, 26], [61, 27], [61, 41], [61, 42], [61, 43], [61, 44], [61, 45], [61, 46], [61, 47], [61, 48], [61, 49], [61, 50], [61, 51], [61, 55], [61, 56], [61, 60], [61, 61], [61, 62], [61, 63], [61, 70], [61, 71], [61, 75], [61, 76], [61, 77], [61, 78], [61, 79], [61, 80], [61, 81], [61, 82], [61, 83], [61, 92], [61, 93], [61, 94], [61, 102], [61, 103], [61, 104], [61, 105], [61, 106], [61, 107], [61, 108], [62, 4], [62, 5], [62, 6], [62, 16], [62, 17], [62, 18], [62, 19], [62, 20], [62, 21], [62, 22], [62, 23], [62, 24], [62, 25], [62, 26], [62, 27], [62, 48], [62, 49], [62, 50], [62, 54], [62, 55], [62, 58], [62, 59], [62, 60], [62, 61], [62, 75], [62, 76], [62, 77], [62, 78], [62, 98], [62, 99], [62, 103], [62, 104], [62, 105], [62, 118], [62, 119], [62, 120], [63, 0], [63, 1], [63, 2], [63, 3], [63, 4], [63, 5], [63, 6], [63, 7], [63, 16], [63, 17], [63, 18], [63, 19], [63, 20], [63, 21], [63, 22], [63, 23], [63, 24], [63, 25], [63, 26], [63, 41], [63, 42], [63, 53], [63, 54], [63, 55], [63, 56], [63, 57], [63, 58], [63, 60], [63, 61], [63, 62], [63, 63], [63, 64], [63, 65], [63, 68], [63, 69], [63, 70], [63, 71], [63, 72], [63, 73], [63, 74], [63, 81], [63, 82], [63, 83], [63, 84], [63, 85], [63, 86], [63, 88], [63, 89], [63, 93], [63, 94], [63, 99], [63, 100], [63, 101], [63, 102], [63, 103], [63, 104], [63, 105], [63, 106], [63, 107], [63, 108], [63, 132], [63, 133], [63, 135], [64, 0], [64, 1], [64, 2], [64, 3], [64, 4], [64, 5], [64, 6], [64, 7], [64, 17], [64, 18], [64, 19], [64, 20], [64, 21], [64, 22], [64, 23], [64, 24], [64, 25], [64, 44], [64, 45], [64, 46], [64, 47], [64, 48], [64, 49], [64, 50], [64, 51], [64, 52], [64, 53], [64, 54], [64, 55], [64, 56], [64, 60], [64, 61], [64, 62], [64, 63], [64, 65], [64, 67], [64, 69], [64, 70], [64, 71], [64, 72], [64, 73], [64, 74], [64, 78], [64, 79], [64, 80], [64, 81], [64, 82], [64, 94], [64, 95], [64, 96], [64, 98], [64, 99], [64, 100], [64, 101], [64, 102], [64, 106], [64, 107], [64, 108], [64, 109], [64, 113], [64, 114], [64, 115], [64, 131], [64, 132], [64, 135], [64, 136], [64, 137], [64, 138], [65, 0], [65, 1], [65, 2], [65, 3], [65, 4], [65, 5], [65, 6], [65, 7], [65, 18], [65, 19], [65, 20], [65, 21], [65, 22], [65, 23], [65, 41], [65, 42], [65, 43], [65, 44], [65, 45], [65, 49], [65, 50], [65, 51], [65, 52], [65, 53], [65, 54], [65, 55], [65, 60], [65, 61], [65, 62], [65, 63], [65, 64], [65, 65], [65, 66], [65, 67], [65, 71], [65, 72], [65, 73], [65, 78], [65, 79], [65, 80], [65, 81], [65, 82], [65, 83], [65, 84], [65, 102], [65, 103], [65, 104], [65, 105], [65, 106], [65, 107], [65, 111], [65, 112], [65, 113], [65, 114], [65, 115], [65, 130], [65, 131], [65, 132], [65, 133], [65, 134], [65, 136], [65, 137], [66, 6], [66, 7], [66, 18], [66, 19], [66, 20], [66, 21], [66, 22], [66, 23], [66, 49], [66, 50], [66, 51], [66, 52], [66, 53], [66, 54], [66, 55], [66, 60], [66, 61], [66, 62], [66, 63], [66, 64], [66, 65], [66, 67], [66, 92], [66, 93], [66, 94], [66, 95], [66, 96], [66, 104], [66, 106], [66, 107], [66, 108], [66, 111], [66, 112], [66, 113], [66, 114], [66, 133], [66, 134], [66, 135], [66, 136], [66, 137], [66, 138], [66, 139], [67, 0], [67, 1], [67, 2], [67, 3], [67, 4], [67, 5], [67, 6], [67, 7], [67, 20], [67, 21], [67, 22], [67, 23], [67, 39], [67, 40], [67, 45], [67, 46], [67, 47], [67, 48], [67, 49], [67, 50], [67, 51], [67, 52], [67, 53], [67, 54], [67, 55], [67, 56], [67, 57], [67, 61], [67, 62], [67, 63], [67, 64], [67, 65], [67, 66], [67, 77], [67, 78], [67, 79], [67, 80], [67, 81], [67, 82], [67, 83], [67, 91], [67, 99], [67, 100], [67, 101], [67, 102], [67, 103], [67, 104], [67, 105], [67, 106], [67, 107], [67, 122], [67, 123], [67, 135], [67, 136], [67, 137], [67, 138], [67, 139], [68, 0], [68, 1], [68, 3], [68, 4], [68, 5], [68, 6], [68, 7], [68, 20], [68, 21], [68, 22], [68, 38], [68, 39], [68, 40], [68, 41], [68, 42], [68, 47], [68, 48], [68, 51], [68, 52], [68, 53], [68, 65], [68, 66], [68, 67], [68, 68], [68, 72], [68, 73], [68, 74], [68, 75], [68, 76], [68, 81], [68, 82], [68, 83], [68, 84], [68, 85], [68, 86], [68, 88], [68, 89], [68, 90], [68, 91], [68, 92], [68, 93], [68, 94], [68, 105], [68, 106], [68, 107], [68, 109], [68, 110], [68, 111], [68, 112], [68, 135], [68, 136], [68, 137], [69, 1], [69, 2], [69, 3], [69, 4], [69, 5], [69, 6], [69, 7], [69, 8], [69, 9], [69, 21], [69, 22], [69, 31], [69, 32], [69, 46], [69, 47], [69, 51], [69, 52], [69, 53], [69, 60], [69, 72], [69, 73], [69, 74], [69, 75], [69, 76], [69, 77], [69, 78], [69, 79], [69, 80], [69, 81], [69, 82], [69, 83], [69, 92], [69, 106], [69, 107], [70, 2], [70, 3], [70, 4], [70, 5], [70, 6], [70, 7], [70, 8], [70, 29], [70, 30], [70, 52], [70, 53], [70, 54], [70, 55], [70, 56], [70, 57], [70, 58], [70, 60], [70, 61], [70, 62], [70, 72], [70, 73], [70, 76], [70, 77], [70, 83], [70, 84], [70, 102], [70, 103], [70, 104], [70, 105], [70, 106], [70, 107], [70, 108], [70, 112], [70, 113], [70, 124], [70, 125], [71, 1], [71, 2], [71, 3], [71, 4], [71, 5], [71, 6], [71, 7], [71, 8], [71, 20], [71, 21], [71, 22], [71, 50], [71, 51], [71, 54], [71, 55], [71, 61], [71, 75], [71, 76], [71, 77], [71, 99], [71, 100], [71, 104], [71, 105], [71, 106], [71, 107], [71, 108], [71, 109], [71, 110], [71, 111], [72, 0], [72, 1], [72, 2], [72, 3], [72, 4], [72, 5], [72, 6], [72, 7], [72, 24], [72, 25], [72, 60], [72, 61], [72, 62], [72, 63], [72, 72], [72, 73], [72, 74], [72, 75], [72, 129], [73, 0], [73, 1], [73, 2], [73, 3], [73, 4], [73, 5], [73, 6], [73, 7], [73, 28], [73, 29], [73, 30], [73, 47], [73, 72], [73, 73], [73, 74], [73, 81], [73, 82], [73, 83], [73, 89], [73, 90], [73, 100], [73, 101], [73, 102], [73, 105], [73, 106], [73, 147], [73, 148], [74, 0], [74, 1], [74, 2], [74, 3], [74, 4], [74, 5], [74, 6], [74, 27], [74, 28], [74, 29], [74, 30], [74, 43], [74, 44], [74, 45], [74, 46], [74, 47], [74, 48], [74, 51], [74, 52], [74, 59], [74, 60], [74, 61], [74, 62], [74, 63], [74, 64], [74, 65], [74, 66], [74, 67], [74, 68], [74, 69], [74, 70], [74, 71], [74, 72], [74, 74], [74, 84], [74, 85], [74, 90], [74, 91], [74, 92], [74, 93], [74, 111], [75, 0], [75, 1], [75, 5], [75, 6], [75, 26], [75, 27], [75, 28], [75, 43], [75, 44], [75, 45], [75, 51], [75, 52], [75, 59], [75, 60], [75, 61], [75, 62], [75, 63], [75, 64], [75, 65], [75, 66], [75, 67], [75, 68], [75, 69], [75, 70], [75, 71], [75, 72], [75, 73], [75, 74], [76, 0], [76, 1], [76, 2], [76, 3], [76, 4], [76, 5], [76, 6], [76, 24], [76, 25], [76, 28], [76, 29], [76, 30], [76, 35], [76, 36], [76, 37], [76, 50], [76, 51], [76, 57], [76, 58], [76, 59], [76, 60], [76, 65], [76, 66], [76, 67], [76, 68], [76, 69], [76, 88], [76, 89], [76, 90], [77, 0], [77, 1], [77, 2], [77, 3], [77, 4], [77, 24], [77, 25], [77, 26], [77, 27], [77, 28], [77, 41], [77, 47], [77, 48], [77, 57], [77, 58], [77, 59], [78, 1], [78, 17], [78, 18], [78, 19], [78, 20], [78, 21], [78, 22], [78, 27], [78, 28], [78, 29], [78, 30], [78, 31], [78, 32], [78, 36], [78, 48], [78, 57], [78, 58], [78, 59], [78, 147], [78, 148], [79, 0], [79, 1], [79, 2], [79, 5], [79, 6], [79, 7], [79, 10], [79, 11], [79, 12], [79, 16], [79, 17], [79, 18], [79, 19], [79, 29], [79, 30], [79, 31], [79, 35], [79, 36], [79, 37], [79, 42], [79, 43], [79, 46], [79, 47], [79, 48], [79, 49], [79, 56], [79, 57], [79, 58], [79, 59], [79, 70], [79, 71], [79, 72], [79, 73], [79, 74], [80, 16], [80, 17], [80, 18], [80, 30], [80, 31], [80, 39], [80, 40], [80, 41], [80, 42], [80, 43], [80, 44], [80, 45], [80, 46], [80, 48], [80, 55], [80, 56], [80, 57], [80, 58], [80, 59], [80, 60], [80, 63], [80, 64], [80, 77], [80, 140], [80, 141], [80, 142], [81, 0], [81, 1], [81, 2], [81, 6], [81, 8], [81, 9], [81, 10], [81, 11], [81, 18], [81, 19], [81, 37], [81, 38], [81, 39], [81, 42], [81, 43], [81, 44], [81, 45], [81, 46], [81, 57], [81, 58], [81, 59], [81, 63], [81, 77], [81, 78], [82, 0], [82, 1], [82, 2], [82, 3], [82, 4], [82, 5], [82, 6], [82, 7], [82, 8], [82, 9], [82, 14], [82, 15], [82, 16], [82, 17], [82, 18], [82, 19], [82, 43], [82, 44], [82, 45], [82, 46], [82, 47], [82, 48], [82, 49], [82, 50], [82, 51], [82, 55], [82, 56], [82, 57], [82, 141], [83, 0], [83, 1], [83, 2], [83, 3], [83, 4], [83, 5], [83, 6], [83, 10], [83, 12], [83, 42], [83, 43], [83, 47], [83, 48], [83, 49], [83, 50], [83, 71], [83, 72], [83, 76], [83, 77], [83, 78], [83, 79], [83, 80], [83, 81], [84, 1], [84, 2], [84, 3], [84, 4], [84, 5], [84, 6], [84, 7], [84, 13], [84, 14], [84, 15], [84, 16], [84, 17], [84, 18], [84, 30], [84, 32], [84, 33], [84, 34], [84, 35], [84, 36], [84, 37], [84, 45], [84, 46], [84, 47], [84, 51], [84, 52], [84, 53], [84, 61], [84, 63], [84, 64], [84, 65], [84, 74], [84, 75], [84, 78], [84, 79], [84, 81], [84, 82], [84, 150], [84, 151], [85, 0], [85, 1], [85, 2], [85, 3], [85, 5], [85, 6], [85, 9], [85, 10], [85, 32], [85, 33], [85, 47], [85, 48], [85, 49], [85, 50], [85, 66], [85, 67], [85, 68], [85, 69], [85, 80], [85, 81], [85, 101], [85, 139], [85, 140], [85, 150], [86, 13], [86, 14], [86, 15], [86, 18], [86, 19], [86, 20], [86, 50], [86, 51], [86, 53], [86, 54], [86, 60], [86, 61], [86, 80], [86, 81], [87, 13], [87, 14], [87, 60], [87, 61], [87, 62], [87, 66], [87, 67], [87, 68], [87, 69], [87, 81], [87, 82], [88, 65], [88, 66], [88, 67], [88, 68], [88, 136], [88, 137], [88, 138], [88, 139], [89, 1], [89, 2], [89, 9], [89, 10], [89, 14], [89, 42], [89, 43], [89, 83], [89, 84], [90, 0], [90, 1], [90, 42], [90, 43], [90, 85], [91, 42], [91, 43], [91, 84], [91, 85], [92, 24], [92, 25], [92, 32], [92, 33], [92, 41], [92, 42], [92, 43], [92, 44], [93, 132], [93, 133], [93, 134], [93, 135], [93, 136], [94, 5], [94, 6], [94, 17], [94, 18], [95, 102], [95, 103], [95, 119], [95, 120], [95, 121], [96, 1], [96, 51], [96, 110], [96, 111], [96, 123], [96, 124], [97, 0], [97, 1], [97, 28], [97, 29], [97, 30], [97, 43], [97, 45], [97, 46], [97, 47], [97, 48], [97, 50], [97, 51], [97, 52], [97, 113], [97, 114], [97, 121], [97, 122], [97, 123], [98, 0], [98, 1], [98, 126], [99, 0], [99, 1], [99, 43], [99, 44], [100, 59], [100, 65], [100, 66], [101, 0], [101, 1], [101, 2], [103, 64], [104, 55], [113, 4], [113, 5]]
#f1_ssvae_2_labels.tolist().index([ 101, 90])
#plt.scatter(f1_ssvae_3_labels[:,1], f1_ssvae_3_labels[:,0], s=1, cmap='Viridis')
Label plot¶
# this plot shows the first 180 spectra the SSVAE model assigns to a specified class
ssvae_label_plot(f1_img2, f1_ssvae_2_labels, f1_wav) # Spectra from class 3
Plotting Results¶
Plot code¶
SSVAE Grain 1 Plot¶
The first image in the figure below is a plot of the latent space color mapped according to the four spectral feature classes defined above. The second image is the hybrid perovskite cell showing the spatial locations of the four classes.
# SSVAE with 40 supervised data points
ssvae_plot("SSVAE Grain 1", f1_ssvae_z_mean, f1_ssvae_z_labels, f1_xpix, f1_ypix, 50)
Spectral label plot¶
# Plot one spectrum from each class in the labeled data
spect_label_plot("Spectral Classes", f1_img2, f1_pts, f1_wav)
Determining latent dimensions¶
# X-axis
f1_ssvae_z_mean_x = f1_ssvae_z_mean[:,0].detach().cpu().numpy()
f1_ssvae_z_mean_x = f1_ssvae_z_mean_x.reshape(f1_ypix, f1_xpix)
print("X Min: ", (f1_ssvae_z_mean_x==np.min(f1_ssvae_z_mean_x)).nonzero())
print("X Max: ", (f1_ssvae_z_mean_x==np.max(f1_ssvae_z_mean_x)).nonzero())
f1_ssvae_z_mean_x_sort = np.dstack(
np.unravel_index(np.argsort(f1_ssvae_z_mean_x.ravel()), (f1_ypix, f1_xpix)))
f1_ssvae_z_mean_x_sort = np.squeeze(f1_ssvae_z_mean_x_sort)
spectra_plot("SSVAE Grain 1 X-Axis", f1_img2, f1_ssvae_z_mean_x_sort, f1_xpix, f1_ypix, f1_wav)
X Min: (array([13]), array([53])) X Max: (array([121]), array([146]))
# Y-axis
f1_ssvae_z_mean_y = f1_ssvae_z_mean[:,1].detach().cpu().numpy()
f1_ssvae_z_mean_y = f1_ssvae_z_mean_y.reshape(f1_ypix, f1_xpix)
print("Y Min: ", (f1_ssvae_z_mean_y==np.min(f1_ssvae_z_mean_y)).nonzero())
print("Y Max: ", (f1_ssvae_z_mean_y==np.max(f1_ssvae_z_mean_y)).nonzero())
f1_ssvae_z_mean_y_sort = np.dstack(
np.unravel_index(np.argsort(f1_ssvae_z_mean_y.ravel()), (f1_ypix, f1_xpix)))
f1_ssvae_z_mean_y_sort = np.squeeze(f1_ssvae_z_mean_y_sort)
spectra_plot("SSVAE Grain 1 Y-Axis", f1_img2, f1_ssvae_z_mean_y_sort, f1_xpix, f1_ypix, f1_wav)
Y Min: (array([114]), array([137])) Y Max: (array([36]), array([18]))
Grain 2 on SSVAE Model 1¶
f2on1_ssvae_z_mean, f2on1_ssvae_z_sd, f2on1_ssvae_z_labels = f1_ssvae.encode(f2_train_data)
f2on1_ssvae_z_mean = normalize(f2on1_ssvae_z_mean)
f1_ssvae_z_sd_6 = normalize(f1_ssvae_z_sd)
f2on1_ssvae_z_mean, f2on1_ssvae_z_sd, f2on1_ssvae_z_labels = f1_ssvae.encode(f2_train_data)
f2on1_ssvae_z_mean = normalize(f2on1_ssvae_z_mean)
f2on1_ssvae_z_sd = normalize(f2on1_ssvae_z_sd)
f2on1_ssvae_z_labels_2d = f2on1_ssvae_z_labels.reshape(f2_ypix,f2_xpix)
f2on1_ssvae_0_labels = (f2on1_ssvae_z_labels_2d == 0).nonzero(as_tuple=False)
f2on1_ssvae_1_labels = (f2on1_ssvae_z_labels_2d == 1).nonzero(as_tuple=False)
f2on1_ssvae_2_labels = (f2on1_ssvae_z_labels_2d == 2).nonzero(as_tuple=False)
f2on1_ssvae_3_labels = (f2on1_ssvae_z_labels_2d == 3).nonzero(as_tuple=False)
ssvae_plot("SSVAE Grain 2 on Grain 1 Model", f2on1_ssvae_z_mean, f2on1_ssvae_z_labels,
f2_xpix, f2_ypix, 33.333333333)
ssvae_label_plot(f2_img2, f2on1_ssvae_2_labels, f2_wav, 180)
custom_spect_labels_2on1 = [f2on1_ssvae_0_labels[0], f2on1_ssvae_1_labels[128],
f2on1_ssvae_2_labels[11], f2on1_ssvae_3_labels[161]]
# Plot one spectrum from each class in the latent representation of the data
custom_spect_label_plot("Classes from Grain 2 on Model 1", f2_img2, custom_spect_labels_2on1, f2_wav)
#f1_decode = f1_ssvae.decode(f1_ssvae_z_mean[0], f1_ssvae_z_labels)